Quando si sviluppa un'applicazione e si sceglie di utilizzare il multithreading per migliorare le prestazioni dei controlli dell'interfaccia occorre fare attenzione, affinché le operazioni che si alternano sullo stesso controllo non generino
race condition e, più in generale,
confitti tra thread.
Uno degli errori più comuni a cui si deve far fronte in questi casi è
InvalidOperationException, ed è relativo a situazioni in cui si cerca di accedere a un controllo creato da un thread all'interno di un altro thread.
Ali Tarhini affronta questo tema nel suo
blog proponendo un
esempio di codice, che genera l'errore appena citato:
Dim nuovo_thread As New Threading.Thread(AddressOf test)
Private Sub test()
TextBox1.Text = "using textbox from another thread"
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
nuovo_thread.Start()
End Sub
Infatti, il thread
nuovo_thread tenta di eseguire l'accesso al controllo
TextBox1 che appartiene, invece, al thread principale.
Per risolvere il problema, bisogna implementare un meccanismo di
context switching e di prevenzione del
deadlock, come si è già detto in precedenti
articoli. Il framework .NET mette a disposizione la proprietà
InvokeRequired: essa restituisce un valore che indica se il chiamante deve invocare un metodo a parte o meno, a seconda che il controllo appartenga al thread corrente o sia stato creato da un altro.
Nel suo articolo, Tarhini mostra con un ulteriore spezzone di codice come sia possibile applicare la proprietà per evitare il verificarsi dell'errore.