Announcement

Collapse
No announcement yet.

Ungültiger Threadübergreifender Vorgang

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Ungültiger Threadübergreifender Vorgang

    Hi,

    ich hab' folgendes Problem:

    Ich starte ein Thread, in dem ein Objekt sich regelmässig updated, mit Daten aus dem Netz. Diese will ich jetzt in meine schöne form zaubern. Das Problem ist, dass ich aus diesem Thread nicht aufm eine Form zugreifen darf. Welche Lösungen gibt es da?

  • #2
    Eine Möglichkeit wäre, deinen Thread ein Event auslösen zu lassen, welches auf der anzeigenden Form aufgefangen wird.
    Innerhalb dieses Delegaten ist es mit Invoke möglich auf die Form zuzugreifen. Also in etwa so:


    Code:
    /// Beide Methoden liegen innerhalb der Form
    
    public void OnThreadEvent()
    {
        EventHandler e = new EventHandler(this.ThreadEvent);
        this.Invoke(e);
    }
    
    private void ThreadEvent(Sender object, EventArgs e)
    {
        // an dieser Stelle kann man vollständig auf die Form zugreifen
    }

    Comment


    • #3
      Hallo,

      ab .NET 2.0 steht die BackgroundWorker-Komponente zur Verfügung, die eine Threadsichere Implementierung von Zugriffen auf die Benutzeroberfläche stark erleichtert.

      Ansonsten sorgt der "Umweg" über ISynchronizeInvoke dafür, dass der Zugriff auf das Control immer aus dem primären Thread der Anwendung heraus erfolgt. Das folgende Beispiel demonstriert dies in Kombination mit den Anonymous Methods von C# 2.0:

      Code:
      delegate void SetLabelWSDelegate(string sMsg);
      
      ...
      
       ISynchronizeInvoke aSync = labelWS1;
       try
       {
         SetLabelWSDelegate aDel = delegate(string sMsg)
         {
           labelWS1.Text = sMsg;
         };
         aSync.Invoke(aDel, new object[] { sWS1 });
       }
       catch
       {
       }
      
      ...

      Comment


      • #4
        Originally posted by Andreas Moeller View Post
        Eine Möglichkeit wäre, deinen Thread ein Event auslösen zu lassen, welches auf der anzeigenden Form aufgefangen wird.
        Innerhalb dieses Delegaten ist es mit Invoke möglich auf die Form zuzugreifen. Also in etwa so:


        Code:
        /// Beide Methoden liegen innerhalb der Form
        
        public void OnThreadEvent()
        {
            EventHandler e = new EventHandler(this.ThreadEvent);
            this.Invoke(e);
        }
        
        private void ThreadEvent(Sender object, EventArgs e)
        {
            // an dieser Stelle kann man vollständig auf die Form zugreifen
        }
        Hi,

        das hat mir erstmal weitergeholfen. Den BackgroupWorker schau ich mit bei Gelegenheit auch mal genauer an

        Danke.

        Comment


        • #5
          Hallo,

          der BackgroundWorker bietet jedoch nur eine rudimentäre Anzahl an Events an. Wenn ich ein eigenes Event in einer abgeleiteten Klasse einbaue bekomme ich trotzdem eine Exception.

          Wie kann ich eigene Events im Backgroundworker threadsicher machen?

          Comment


          • #6
            Hallo,

            die BackgroundWorker-Komponente setzt nicht das Win32-Regelwerk außer Kraft! Auf ein Control darf nur der Thread zugreifen, der dieses auch erzeugt hat (auch bei .NET ist jedes Control noch ein Win32-Fenster).

            Wenn innerhalb des separaten Threads (also in der Ereignisbehandlungsmethode für das BackgroundWorker-Ereignis DoWork) die vom primären Thread der Anwendung kontrollierte Benutzeroberfläche aktualisiert werden soll, müssen diese Aufrufe im Kontext des primären Threads erfolgen. Diese Forderung wird zum Beispiel dann erfüllt, wenn der Zugriff über ISynchronizeInvoke erfolgt.

            Nur dann, wenn das BackgroundWorker-Ereignis RunWorkerCompleted für die Aktualisierung der Benutzeroberfläche am Ende des separaten Threads ausreicht, verbirgt der BackgroundWorker die Thread-Regeln. Die Ereignisbehandlungsmethode für RunWorkerCompleted wird automatisch im primären Thread der Anwendung ausgeführt.

            Comment


            • #7
              Danke Andreas.

              Another way to Invoke UI from a Worker Thread - Dort steht das alles nochmal ausführlich.

              Comment

              Working...
              X