Gründe, die Kontrolle.BeginInvoke würde, nicht führen Sie eine Stellvertretung?

Übersicht

Gibt es Erklärungen für die Kontrolle.BeginInvoke() nicht ausführen, ein Delegat, der es übergeben wird?

Code-Beispiel

Haben wir angenommen, das folgende Muster in unserem Winforms-Anwendungen sicher ausführen UI-bezogenen Arbeit auf dem UI-thread:

private Control hiddenControl = new Control();

private void uiMethod()
{
  MethodInvoker uiDelegate = new MethodInvoker(delegate()
  {
    Logging.writeLine("Start of uiDelegate");
    //ui releated operations
    childDialog = new ChildDialog();
    childDialow.show();
    Logging.writeLine("End of uiDelegate");
  });

  if (hiddenControl.InvokeRequired)
  {
    Logging.writeLine("Start of InvokeRequired block");
    hiddenControl.BeginInvoke(uiDelegate);
    Logging.writeLine("End of InvokeRequired block");
  }
  else
  {
    uiDelegate();
  }
}

Hier, wir erstellen ein Steuerelement "hiddenControl" ausdrücklich für den Zweck der Delegierten auf dem UI-Thread. Wir haben nie Aufruf von endInvoke, weil es anscheinend nicht erforderlich für die Steuerung.BeginInvoke und wir müssen nie um einen Wert zurückzugeben, weil unsere Methoden einfach manipulieren UI, sowieso.

Zwar sehr ausführliche, dieses Muster scheint zu sein, ein relativ gut angenommen Lösung. Es gibt jedoch einige Beweise, dass auch dieses Muster kann nicht gut funktionieren in allen Situationen.

Beobachtungen

Ich bin nicht ausschließt, eine Anwendung, die Fehler und die Schuld WinForms. Nachdem alle, wählen Sie die wahrscheinlich nicht kaputt. Allerdings bin ich an einem Verlust zu erklären, warum ein Delegierter kann scheinbar gar nicht laufen.

In unserem Fall, wir beobachten manchmal, dass die "Start uiDelegate" log-Nachricht wird nie ausgeführt, in bestimmten threading-Szenarien, auch wenn die "Starten von InvokeReqiured block" und "End of InvokeRequired block" erfolgreich ausgeführt.

Es ist schon sehr schwer zu replizieren dieses Verhalten, weil unsere Anwendung wird geliefert, wie eine DLL, unseren Kunden führen Sie es in Ihre eigenen Anwendungen. Deshalb können wir nicht garantieren, wie oder in welchem thread diese Methoden aufgerufen werden können.

Wir ausgeschlossen UI-thread blockieren, weil es wird beobachtet, dass die UI nicht sperren. Vermutlich, wenn das UI aktualisiert wird, dann wird die Nachricht, die Pumpe ist funktionsfähig und für das abrufen von Nachrichten aus der message queue und die Ausführung Ihrer Delegierten.

Zusammenfassung

Angesichts dieser Informationen, gibt es alles, was wir versuchen können, um diese Anrufe mehr Kugel-Beweis? Wie bereits erwähnt, haben wir relativ wenig Kontrolle über andere threads in einer Anwendung, und nicht kontrollieren, in welchem Kontext diese Methoden aufgerufen werden.

Was Sie beeinflussen können, wie die Delegierten erfolgreich zu Steuern.BeginInvoke() ausführen, oder nicht?

InformationsquelleAutor Chris Scott | 2012-01-23
Schreibe einen Kommentar