Iată punctele importante:
- Nu puteți efectua apeluri de control UI dintr-un fir diferit de cel pe care au fost create (firul formularului).
- Invocațiile delegate (de exemplu, cârligele de evenimente) sunt declanșate pe același fir ca și obiectul care trage evenimentul.
Deci, dacă aveți un fir separat "motor" care face ceva lucru și are unele UI uitam de schimbări de stat care pot fi reflectate în UI (cum ar fi un bara de progres sau orice altceva), aveți o problemă. Incendiul motorului este un eveniment schimbat de obiecte care a fost atras de Formular. Dar delegatul de apel invocă faptul că Formularul înregistrat cu motorul este chemat pe firul motorului? nu pe firul Formularului. Deci, nu puteți actualiza comenzile de la acel apel invers. Doh!
BeginInvoke comes to the rescue. Just use this simple coding model in all your callback methods and you can be sure that things are going to be okay:
private delegate void EventArgsDelegate(object sender, EventArgs ea);
void SomethingHappened(object sender, EventArgs ea)
{
//
// Make sure this callback is on the correct thread
//
if (this.InvokeRequired)
{
this.Invoke(new EventArgsDelegate(SomethingHappened), new object[] { sender, ea });
return;
}
//
// Do something with the event such as update a control
//
textBox1.Text = "Something happened";
}
E foarte simplu.
- Utilizați InvokeRequired pentru a afla dacă acest apel invers a avut loc pe firul corect.
- Dacă nu, reinvocați apelul pe firul corect cu aceiași parametri. Puteți reinventa o metodă utilizând metodele Invocați (blocare) sau BeginInvoke (fără blocare).
- Data viitoare când funcția este apelată, InvokeRequired returnează false deoarece suntem acum pe firul corect și toată lumea este fericită.
Acesta este un mod foarte compact de abordare a acestei probleme și de a face ca Formularele dvs. să fie sigure de apelurile de apel cu mai multe fire.