Threads in WinForms über Logik synchronisieren  
Frank Dzaebel, erstellt am: 5.4.2006, zuletzt geändert:  5.4.2006
Kategorie: Threading, .NET-Version: 1.1, [Download]

Hier wird ein Beispiel gegeben, wie Threads über Logik (hier boolesche Variablen) synchronisiert werden und selbsttätig auslaufen.
Speziell im Windows Forms Bereich sollte nach dem Start von Threads zeitnah die aufrufende Methode beendet werden, damit die MessageLoop die Applikation reagierend halten kann. Hier werden zwei "long running" Threads gestartet und ein Event (AllCompleted) ausgelöst, wenn beide Threads fertig sind.


Form1.cs: 
private void button1_Click(object sender, System.EventArgs e)
{ Threads.AllCompleted+=new ConThreadWinForm.Threads.CompletedHandler(Threads_AllCompleted);
  Threads.DoLongRunningOperation1();
  Threads.DoLongRunningOperation2();
}
private void Threads_AllCompleted()
{ MessageBox.Show("Threads sind fertig :)");
}

Threads.cs:
using System;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;

namespace ConThreadWinForm
{
  /// <summary>Threads in WinForms synchronisieren unter .NET 1.1</summary>
  public class Threads
  {
    public static volatile bool completed1=false;
    public static volatile bool completed2=false;
    public static volatile bool allCompleted=false;

    public static void DoLongRunningOperation1()
    {
      if (!IsAllCompletedSubscribed()) return;
      new Thread(new ThreadStart(RunTestScript1)).Start();   
    }

    public static void DoLongRunningOperation2()
    {
      if (!IsAllCompletedSubscribed()) return;
      new Thread(new ThreadStart(RunTestScript2)).Start();   
    }
    public delegate void CompletedHandler(); 
    static public event CompletedHandler AllCompleted;
   
    private static bool IsAllCompletedSubscribed()
    {
      if (AllCompleted == null) 
      {
        MessageBox.Show("Please subscribe to AllCompleted Event");
        return false;
      } return true;
    }
    public static void RunTestScript1() 
    {
      TestClass.RunTestScript1(); completed1=true;
      if (completed2 && !allCompleted) 
        { allCompleted=true; AllCompleted();}
    }
    public static void RunTestScript2() 
    {
      TestClass.RunTestScript2(); completed2=true;
      if (completed1 && !allCompleted) 
        { allCompleted=true; AllCompleted();}
    }
  }

  class TestClass
  {
    public static void RunTestScript1() 
    {
      Debug.WriteLine("RunTestScript1 wird ausgeführt");
      Thread.Sleep(3456); // lange Operation 
      Debug.WriteLine("RunTestScript1 beendet.");
    }
    public static void RunTestScript2() 
    {
      Debug.WriteLine("RunTestScript2 wird ausgeführt");
      Thread.Sleep(4567); // lange Operation
      Debug.WriteLine("RunTestScript2 beendet.");
    }
  }
}