.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.

Share this content: