PDA

View Full Version : [C# 2.0]Operazione cross thread non valida


RaouL_BennetH
15-06-2010, 18:31
:(

Buonasera a tutti :)

Cerco di descrivere per bene il problema:

Ho una dll che fornisce due classi:

1) GridHelper;
2) UIAsyncWorker;

Questa dll è referenziata nel mio progetto (di tipo windows forms).

Il GridHelper è uno UserControl che non fa altro che darmi un binding navigator ed una datagridview già formattate sul form, ad esempio:



gridHelper = new GridHelper();
this.SomePanel.Controls.Add(gridHelper);



Ora, sempre all'interno del form, utilizzo anche l'altra classe UIAsyncWorker, che mi fornisce un backgroundworker che prende un metodo anonimo per eseguire diverse operazioni, ad es.:



worker = new UIAsyncWorker();
worker.RunWorkAsync(MetodoQualsiasi);



e fin qui, tutto mi funziona.

Il problema lo ho quando devo associare una fonte dati al gridHelper:



try
{
worker = new UIAsyncWorker();
worker.InvokeCallBack = delegate()
{
myBindingSource.DataSource = myDataGetFromSomeWhere;
gridHelper.BindGridAsync(myBindingSource);
};
worker.RunAsync();
}
catch(Exception ex)
{
//bla
}



L'errore che mi da è:


Operazione cross-thread non valida:
e' stato eseguito l'accesso al controllo datagridview da un thread
diverso da quello da cui è stata eseguita la creazione


il controllo 'datagridview' si trova appunto su 'gridHelper' che viene soltanto aggiunto a runtime al mio Form, quindi, giustamente, mi va in errore.

Come potrei risolvere, considerando che:

Non ho accesso e non posso modificare ne gridHelper ne UIAsyncWork ?!?

grazie mille a tutti :)

RaouL.

^TiGeRShArK^
15-06-2010, 20:55
devi usare il BeginInvoke sul controllo per lanciare quelle operazioni sul thread della UI.
Qualcosa del genere verrebbe:

myBindingSource.BeginInvoke(SetDataSource);

private void SetDataSource()
{
myBindingSource.DataSource = myDataGetFromSomeWhere;
gridHelper.BindGridAsync(myBindingSource);
}

RaouL_BennetH
16-06-2010, 12:30
devi usare il BeginInvoke sul controllo per lanciare quelle operazioni sul thread della UI.
Qualcosa del genere verrebbe:

myBindingSource.BeginInvoke(SetDataSource);

private void SetDataSource()
{
myBindingSource.DataSource = myDataGetFromSomeWhere;
gridHelper.BindGridAsync(myBindingSource);
}


Ciao e innanzitutto grazie per la risposta :)

Non so se per mia mancanza o altro, ma il 'bindingsource' non mi presenta un metodo BeginInvoke :(

^TiGeRShArK^
16-06-2010, 12:39
devi invocare il BeginInvoke sul controllo che devi aggiornare...
Dal nome non capivo bene qual'e' il controllo, comunque tutti i controlli hanno BeginInvoke.

RaouL_BennetH
16-06-2010, 12:44
devi invocare il BeginInvoke sul controllo che devi aggiornare...
Dal nome non capivo bene qual'e' il controllo, comunque tutti i controlli hanno BeginInvoke.

Quindi dovrebbe essere il mio "gridHelper".

Facendo così:



gridHelper.BeginInvoke(SetBindingSource);


private void SetBindingSource()
{
myBindingSource.DataSource = myDataGetFromSomeWhere;
gridHelper.BindGridAsync(myBindingSource);
}



ottengo un errore in compilazione:


Cannot convert from 'method group' to 'System.Delegate'


Credo giustamente perchè il metodo 'BeginInvoke' chiede come parametro un Delegate.