Passaggio di parametri Cross Thread

lunedì 15 ottobre 2012 - 15.33
Tag Elenco Tags  C#  |  .NET 4.0  |  Windows 7  |  Visual Studio 2010

Spartacus Profilo | Newbie

Ciao a tutti,
MI trovo con questo che per me è un grosso problema.
Sto scrivendo un'applicazione multitrhead perchè devo gestire lunge sequenze di ricezione ed elaborazione dati ma non voglio che l'interfaccia utente mi si blocchi ed anzi da interfaccia devo poter interrompere in modo controllato la ricezione dei dati.
ho risolto in questo modo:

public void Delegate59S1()
{
funzione che riceve i dati;
}

public void button1_Click(object sender, EventArgs e)
{
prova = new Thread(Delegate59S1);
prova.Start();
}

come descritto sopra mi funziona quando non devo passare parametri per la ricezione dati.
Ora mi trovo nella necessità di passare al nuovo Thread i parametri di tipo string StartF, StopF, tStart
ho provato a scrivere il seguente codice
public void Delegate59S2(string StartF, string StopF, string tStart)
{
funzione che riceve i dati(StartF, StopF, tStart);
}
public void button2_Click(object sender, EventArgs e)
{
prova = new Thread(Delegate59S2);
string[] param = new string[] {StartF, StopF, tStart};
prova.Start(param);

ma non mi funziona.
Qualcuno di voi riesce a darmi una mano per farmi capire cosa sbaglio?
Grazie mille a tutti per la gentilezza
}

Vinsent Profilo | Senior Member

Non conosco il C# però a "grandi linee..." riesco a capirne il "perchè", ho provato a fare la stessa cosa in VB e non so perchè il thread accetta un solo parametro, cioè...
così funziona:
Private Sub funzione(ByVal a As String) Console.WriteLine(a) End Sub Private Sub Button1_Click() Handles Button1.Click Dim proc As New Thread(AddressOf funzione) proc.Start("ciao") End Sub

così NON funziona:
Private Sub funzione(ByVal a As String, ByVal b As String) Console.WriteLine(a & b) End Sub Private Sub Button1_Click() Handles Button1.Click Dim proc As New Thread(AddressOf funzione) proc.Start("ciao", "riciao") End Sub
e ritorna un errore "risoluzione dell' overload ecc...".

L' unico modo, che mi è venuto in mente, per aggirare il problema e quello di usare una classe:
Imports System.Threading Public Class Form1 Private Sub Button1_Click() Handles Button1.Click Dim my_function1 As New my_function my_function1.param1 = "qui " my_function1.param2 = "quo " my_function1.param3 = "qua" Dim proc As New Thread(AddressOf my_function1.start) proc.Start() End Sub Public Class my_function Public param1 As String Public param2 As String Public param3 As String Public Sub start() funzione(param1, param2, param3) End Sub Private Sub funzione(ByVal a As String, ByVal b As String, ByVal c As String) Console.WriteLine(a & b & c) End Sub End Class End Class

ciao

Spartacus Profilo | Newbie

Ciao Vinsent, prima di tutto ti ringrazio per la a preziosa risposta, io non conosco molto bene il vb ma mi pare di aver capito che tu usi la classe creata come un contenitore per incapsulare i parametri e che, questi parametri devono essere passati alla classe nel momento in cui richiamo il costruttore ho capito bene?
Quello che però mi pare strano è che ho provato anche passando un array di stringe che dovrebbe essere considerato dal compilatore come un'unica entità.
Oggi proverò a implementare quello che ho capito della tua risposta e poi posterò il risultato qui in forum, per il momento grazie ancora.

Vinsent Profilo | Senior Member

>Quello che però mi pare strano è che ho provato anche passando
>un array di stringe che dovrebbe essere considerato dal compilatore
>come un'unica entità.
Con il dato di fatto (non nè ho ancora compreso il "perchè"....) che il thread non accetta più di un argomento, credo di aver capito come sistemare il tuo codice, in 'Delegate59S2' assegni tre parametri 'string' mentre quando dai lo start al thread ne passi uno (l' array) che contiene tre stringhe quindi in 'Delegate59S2' basta che sostituisci i tre parametri string con un' array di string, poi all' interno della funzione devi gestirti gli elementi dell' array...esempio sempre in VB:
Private Sub Button1_Click() Handles Button1.Click Dim a() As String = New String() {"qui", "quo", "qua"} Dim proc As New Thread(AddressOf funzione) proc.Start(a) End Sub Private Sub funzione(ByVal param() As String) For i = 0 To param.Count - 1 Console.WriteLine(param(i)) Next End Sub

Comunque penso ti convenga inserire tutto (compreso il thread) in una o più classi, dipende se le "ricezioni/elaborazioni dati" le crei a runtime o sono un numero predefinito. In questo modo sarebbe più semplice gestire i thread attraverso property, function, eventi, procedure, ecc...

ciao

Spartacus Profilo | Newbie

Ciao, purtroppo ho ancora dei problemi con questo maledetto passaggio di parametri cross-thread, adesso riesco a far compilare il mio programma, ma poi, a runtime, ottengo un'eccezzione del tipo invalid operation exception riportante il seguente messaggio: Il thread è stato creato con un delegato ThreadStart che non accetta parametri.

posto il mio codice sperando vivamente che qualcuno mi possa aiutare, purtroppo questo è un progetto importante e non riesco a venire a capo di questa cosa

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Ringrazio fin da ora chi vorrà tentare di aiutarmi, è importantissimo

Spartacus Profilo | Newbie

Ciao a tutti ragazzi, scusate se insisto, non mi piace farlo, ma stavolta sono proprio disperato, il progetto è importante e ho bisogno almeno di qualche indizio per la soluzione. grazie mille a tutti

Spartacus Profilo | Newbie

Riciao a tutti quanti, finalmente sono riuscito a capire dove stava il "problema" e quindi a risolvere.
Posto la soluzione per utilità(?!?!) della community.
praticamente il problema è dato dal fatto che quando si devono passare dei parametri al nuovo Thread è necessario fare ricorso al Delegato ParametrizedThreadStart a cui passare il metodo che il thread deve lanciare. Una limitazione è che questo metodo non può accettare parametri tipizzati, ma solamente object che poi alla necessità vanno castati all'interno del metodo. scrivo i frammenti di codice sperando di essere chiaro

public void MyDelegate(object _obj) { string[] _dati = (string[]) _obj) foreach(string message in _dati) { Console.WriteLIne(message); } } private void button1_Click(object sender, EventArgs e) { ParametrizedThreadStart pStart = new ParametrizedThreadStart(MyDelegate) string _data = new string[] {"Ciao", "mondo", "crudele"}; Thread tr = new Thread(pStart); tr.Start(_data); }

Spero vivamente che sia utile ad altri
Ciao e grazie a tutti per il costante aiuto.

Chiedo ai moderatori se possono segnalare come Risolto questo Thread grazie
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5