Cross-Thread invalido su chiamata asincrona

giovedì 24 luglio 2008 - 17.47

netaddicted Profilo | Newbie

Ciao, rieccomi con un enorme punto di domanda sulla testa.

ho un problema sulla chiamata asincrona a un Web
Service.

Vado punto per punto:

nel codice ho questa delegate:
"Public Delegate Sub AsyncMethodCaller(ByVal a As Integer, ByVal b As Integer, _
ByRef q As Integer, ByRef r As Integer)"

questa delegate ha la firma di un web service che voglio chiamare.

Il web service è istanziato in una variabile globale del form che
si chiama "_Operazioni".

Una procedura chiamata 'btnAsyncDivInt_Click' gestisce il click di un pulsante
chiamato appunto btnAsyncDivInt', che effettua la chiamata asincrona
in questo modo:

1_ creo una istanza delle delega passando il metodo del web service che
si chiama 'DivisioneIntera', quindi:

"Dim caller As New AsyncMethodCaller(AddressOf _Operazioni.DivisioneIntera)"

2_ Ottengo i primi 2 parametri da passare alla delegate. Si tratta del contenuto di 2
textbox da convertire in intero:

Dim a, b As Integer
a = Convert.ToInt32(txtA.Text)
b = Convert.ToInt32(txtB.Text)

3_ Finalmente faccio la chiamata asincrona e la assegno a una variabile di tipo
"IAsyncResult":

Dim AsyRes As IAsyncResult = caller.BeginInvoke(a, b, qGLOB, rGLOB, _
AddressOf Callback, caller)

Vorrei fare notare che gli ultimi 2 parametri del metodo chiamato (e cioè le variabili passate
per riferimento: "qGLOB" e "rGLOB") sono globali.

La procedura "Callback" è quella classica usata per recuperare il risultato
di una chiamata asincrona, ecco il codice:

"Public Sub Callback(ByVal AsyRes As IAsyncResult)
' Ritrovo la delegate...
Dim caller As AsyncMethodCaller = CType(AsyRes.AsyncState, AsyncMethodCaller)

'Il risultato della chiamata consiste nel settaggio delle 2 variabili globali
'passate per riferimento:
caller.EndInvoke(qGLOB, rGLOB, AsyRes)

'QUI' ARRIVANO I GUAI!
Me.txtQ.Text = qGLOB.ToString
Me.txtR.Text = rGLOB.ToString

End Sub"

Quando viene eseguita la prima istruzione che segue il commento:
"QUI' ARRIVANO I GUAI", ricevo questo errore:

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

Quindi deduco che la procedura "Callback" viene processata su un thread separato
a cui non è consentito modificare controlli creati da un altro thread.

C'è una soluzione (altra che settare la proprietà "CheckForIllegalCrossThreadCalls"
su "false") per effettuare la chiamata in "thread-safe" mode?

Se qualcuno è ferrato, potrebbe spiegarmi il concetto che sta dietro alla soluzione?
Vorrei capire.

Forse bisogna creare un riferimento al form nella procedura "Callback"
in un modo complesso?

Grazie per l'aiuto,
Francesco Torre (MCP .Net Developer)

lbenaglia Profilo | Guru

>Ciao, rieccomi con un enorme punto di domanda sulla testa.
>
>ho un problema sulla chiamata asincrona a un Web
>Service.

Ciao Francesco,

Questa stanza è dedicata ai DBMS (SQL Server 2000/2005, Express, Access, MySQL, Oracle) pertanto ti invito a postare la tua richiesta nell'apposita stanza dedicata ai Web Services:
http://www.dotnethell.it/forum/XML-XSL-WebServices.aspx

>Grazie per l'aiuto,
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
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-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5