Home   Cover Cover Cover Cover
 

Threads

Beispiel "Einfacher Thread"

Zeigt zwei Threads die abwechselnd das Zeichen 'x' bzw. das Zeichen 'o' auf der Konsole ausgeben.

../../../samples/4/Threading/SimpleThread.cs
using System;
using System.Threading;

namespace Kapitel4.Threading {
  
  public class ThreadExample {
    public static void RunT0() {
      for (int i=0; i<10; i++) { 
        Console.Write("x");
        Thread.Sleep(1000);  
      }
    }
  
    public static void RunT1() {
      for (int i=0; i<10; i++) { 
        Console.Write("o");
        Thread.Sleep(1000);  
      }
    }

    public static void Main() {
      Thread t0 = new Thread(new ThreadStart(RunT0));
      t0.Start();
      Thread t1 = new Thread(new ThreadStart(RunT1));
      t1.Start();
    }
  }
}




Beispiel "Abbruch eines Thread mit der Methode Abort"

Zeigt wie ein Thread durch den Aufruf der Methode Abort() abgebrochen werden kann.

../../../samples/4/Threading/AbortExample.cs
using System;
using System.Threading;

namespace Kapitel4.Threading {
  
  public class ThreadAbort {

    public static void Go() {
      try {
        while (true) Console.Write("X"); //Endlosschleife!!
      } catch (ThreadAbortException e) {
        Console.WriteLine(e.Message);
      }
    }

    public static void Main() {
      Thread t = new Thread(new ThreadStart(Go));
      t.Start();
      Thread.Sleep(5000);  // Der Main-Thread wird f�r 5000ms angehalten, wobei der
      // Thread t aber weiterl�uft.
      t.Abort();
      t.Join();
      Console.WriteLine("fertig");
    }  
  }
}




Beispiel "Alternativer Abbruch eines Thread mit Laufbedingung"

Zeigt wie ein Thread durch setzen einer Laufbedingung eleganter beendet werden kann.

../../../samples/4/Threading/AbortAlternativeExample.cs
using System;
using System.Threading;

namespace Kapitel4.Threading {
  
  public class ThreadAbortAlternative {
    static bool running = true;

    public static void Go() {
      while (running) Console.Write ("X");
    }

    public static void StopThread() {
      running = false;
    }

    public static void Main() {
      Thread t = new Thread(new ThreadStart(Go));
      t.Start();
      Thread.Sleep(5000);
      Console.WriteLine("Thread was being aborted");
      StopThread();
    }
  }
}




Beispiel "Threadpools"

Zeigt wie verschiedene Aufgaben zu sogenannten ThreadPools gruppiert werden können.

../../../samples/4/Threading/ThreadPooling.cs
using System;
using System.Threading;

namespace Kapitel4.Threading {
  
  public class ThreadPooling {

    public static void WorkerProcess(object state) {
      while(true) {  // endlos lange Aufgabe
        Thread.Sleep(2000);  
        Console.WriteLine("WorkerProcess:{0}",state);
      }
    }
  
    public static void TinyWorkerProcess(object state) {
      Thread.Sleep(5000);  // kurze Aufgabe
      Console.WriteLine("TinyWorkerProcess:{0}",state);
    }

    public static void Main(string[] argv) {
      int wThreads;  // WorkerThreads
      int asIO; // Asynchrone IO-Threads
    
      // Wie viele WorkerThreads stehen den verschiedenen Aufgaben maximal zur
      // Verf�gung? 
      ThreadPool.GetMaxThreads(out wThreads,out asIO);
      Console.WriteLine("Max. WorkerThreads:{0}",wThreads);
      Console.WriteLine("Max. Asynchronous IO/Threads:{0}",asIO);
  
      // 3 Arbeitsaufgaben werden angelegt
      for(int i=0;i <3;i++) {
        ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerProcess),i);
      }
    
      // zus�tzlich werden noch 3 weitere Aufgaben festgelegt, die 5000ms warten
      // und dann nur eine Ausgaben durchf�hren, bevor sie wieder beendet werden.
      for(int i=0;i <3;i++) {
        ThreadPool.QueueUserWorkItem(new WaitCallback(TinyWorkerProcess),i);
      }
  
      // st�ndige Kontrolle wie viele WorkerThreads aktuell noch zur Verf�gung stehen 
      while(true) { // Endlosschleife!!
        Thread.Sleep(5000);
        ThreadPool.GetAvailableThreads(out wThreads,out asIO);
        Console.WriteLine("Aktuell verf�gbare WorkerThreads:{0}",wThreads);
        Console.WriteLine("Aktuell verf�gbare IO/Threads:{0}",asIO);
      }
    }
  }
}




Beispiel "Lock"

Zeigt wie zwei Threads mit der Lock-Anweisung synchronisiert werden können.

../../../samples/4/Threading/Lock.cs
using System;
using System.Threading;

namespace Kapitel4.Threading {

  public class LockExample {
  
    public void RunT0() {
      lock (this) {
        for (int i = 0; i < 10; i++) { 
          System.Console.Write("x");
          Thread.Sleep(1000);  
        }
      }
    }
  
    public void RunT1() {
      lock (this) {
        for (int i = 0; i < 10; i++) { 
          System.Console.Write("o");
          Thread.Sleep(1000);  
        }
      }
    }  

    public static void Main() {
      LockExample ex = new LockExample();
      new Thread(new ThreadStart(ex.RunT0)).Start();
      new Thread(new ThreadStart(ex.RunT1)).Start();
    }
  }
}




Beispiel "Monitor"

Implementiert eine Queue-Klasse zu der Elemente blockierend und nicht blockierend hinzugefügt werden können.
../../../samples/4/Threading/Monitor.cs
using System;
using System.Collections;
using System.Threading;

namespace Kapitel4.Threading {

  public class MonitorExample {
    Queue lpt;  // line printer queue
  
    public void AddBlocking(object elem) {
      lock (lpt.SyncRoot) {
        lpt.Enqueue(elem);
      }
    }
  
    public bool AddNonBlocking(object elem) {
      if (!Monitor.TryEnter(lpt.SyncRoot)) return false;
      try {
        lpt.Enqueue(elem);
      } finally {
        Monitor.Exit(lpt.SyncRoot);
      }
      return true;
    }
  }
}

Beispiel "Wait und Pulse"

Zeigt die Verwendung der Methoden Wait und Pulse der Klasse Monitor.
../../../samples/4/Threading/WaitPulse.cs
using System;
using System.Threading;

namespace Kapitel4.Threading {

  public class Buffer {
    const int size = 16;
    char[] buf = new char[size];
    int head = 0, tail = 0, n = 0;          // n = F�llstand
  
    public void Put(char ch) {
      lock(this) {
        while (n >= size) Monitor.Wait(this);      // Puffer voll
        buf[tail] = ch; tail = (tail + 1) % size; n++;
        Monitor.Pulse(this);      // wecke evtl. wartenden Get-Thread
      }
    }
  
    public char Get() {
      lock(this) {
        while (n <= 0) Monitor.Wait(this);      // Puffer leer
        char ch = buf[head]; head = (head + 1) % size; n--;
        Monitor.Pulse(this);      // wecke evtl. wartenden Put-Thread
        return ch;
      }
    }
  }
}