.NET Threading: WaitHandle mit ManualResetEvents

Am Wochenende habe ich ein Problem im Bereich .NET-Threading gelöst, das mich schon seit Wochen beschäftigt hat.

Ich habe eine Menge Threads die sich an den Daten einer Queue bedienen (.Dequeue())und die Ergebnisse in eine Liste zurückspeichern. Die Threads sind unabhängig voneinander. Nach dem Abschluß aller Threads sind die Ergebnisse weiterzuverarbeiten und die Queue, für den nächsten Durchlauf, erneut zu füllen.

Mein Problem war dabei das Warten auf die Beendigung aller Threads. Ich habe dazu eine kleine Testapplikation gebaut und das Problem mit ManualResetEvents gelöst:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

namespace ThreadDemo

{

class Program

{

public static int MaxThreads = 64;

public static ManualResetEvent[] ManualResetEvents = new ManualResetEvent[MaxThreads];

static void Main(string[] args)

{

Thread[] Threads = new Thread[MaxThreads];

for (int i = 0; i < MaxThreads; i++)

{

Threads[i] = new Thread(new ParameterizedThreadStart(worker));

ManualResetEvents[i] = new ManualResetEvent(false);

Threads[i].Start(i);

}

WaitHandle.WaitAll(ManualResetEvents);

Console.WriteLine(“Press any key to continue …”);

Console.Read();

}

public static void worker(object value)

{

int i = (int)value;

//do somthing

ManualResetEvents[i].Set();

}

}

}

Wichtig ist dabei für jeden Thread einen ManualResetEvent anzulegen („ManualResetEvents[i] = new ManualResetEvent(false);“) und dem Thread über den ParameterizedThreadStart den Threadindex mitzugeben. Über diesen Index kann dann aus dem worker-Thread heraus der ManualResetEvent angesprochen werden („ManualResetEvents[i].Set();“). In der Mainmethode wartet man dann auf den Abschluss aller Threads mit der WaitAll-Methode („WaitHandle.WaitAll(ManualResetEvents);“).

Beachten sollte man dabei, dass man damit maximal 64 Threads verarbeiten kann, denn es können nicht mehr als 64 ManualResetEvents verwaltet werden.

Ein Gedanke zu „.NET Threading: WaitHandle mit ManualResetEvents

  1. Thread myThread;
    List threads;
    threads = new List();
    for (int i = 0; i < numThreads; i++)
    {
    myThread = new Thread(new ThreadStart(MyThreadProc));
    threads.Add(myThread);

    myThread.Name = String.Format("Thread{0}", i + 1);
    myThread.Start();
    }
    //Hier wird gewartet bis alle Threads zu Ende sind,
    //eigentlich ist das viel einfacher, oder?
    foreach (Thread th in threads)
    th.Join();

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>