| 

.NET C# Java Javascript Exception

7
Ich hab einen Arbeiter Thread, im Beispiel dargestellt durch den "workThread" dieser brauch eine Zeit um Abgearbeitet zu werden. Ein zweiter Thread "notifyThread" soll auf diesen warten und nach einer Periode ausgeben, wenn der WorkerThread noch nicht beendet wurde.

Im Beispiel hab ich recht Kurze in Warheit kann der workerTread bis zu eine Stunde laufen. Die Notification soll alle 5 Minuten erfolgen.

Über
(!Monitor.Wait(_syncRoot, 1000))
wollte ich nun die Meldung ausgeben, wenn nach 1 sec der WorkerThread nicht beendet ist. Für mein verständniss müsste ich nach dem Timeout ein false zurück erhalten. Es scheint aber so, dass Wait dennoch bis zum Pulse des Worker Threads Blockiert und dann immer "false" zurückliefert.

Wo ist mein Denkfehler?
Was genau bewirkt der timeOut?

static void Main(string[] args)
{
Thread notifyThread = new Thread(NotificationThread);
Thread workThread = new Thread(WorkerThread);

notifyThread.Start();
workThread.Start();

workThread.Join();
}

private static void WorkerThread()
{
Thread.Sleep(15);
lock (_syncRoot)
{
//Work Starts
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(1000);
}
// Work Finished
Console.WriteLine("Pulse");
Monitor.PulseAll(_syncRoot);


}
}

private static void NotificationThread()
{
lock(_syncRoot)
{
Console.WriteLine("Init Wait");
Thread.Sleep(1000);
Console.WriteLine("Start Wait");
Monitor.PulseAll(_syncRoot);
while (!Monitor.Wait(_syncRoot, 1000))
{
Console.WriteLine("Still Waiting for work");
Monitor.PulseAll(_syncRoot);
}
Console.WriteLine("Finished Waiting");
}
Console.WriteLine("Finished Process");
}
11.10.2011
danielw 118 6
1 Antwort
1
Hallo Daniel,

muss es denn zwingend ein Monitor sein?
Ich hab ehrlich gesagt schon einen Moment gebraucht, um Deine Intention (ausgedrückt durch Deinen Beispiel-Code, der einen Monitor verwendet) zu verstehen. Ich bin ein Freund des "intention revealing code" und wenn ich Dich richtig verstanden habe, hast Du

  • einen WorkerThread, der lange schuften muss und
  • einen Monitoring Thread, der die Beendigung des WorkerThreads überwacht und zwischendrin mal eine Benachrichtigung vom Typ "der WorkerThread ist noch nicht fertig" ausgibt.

Aus genau diesen Gründen würde ich das zweiteilen:
1. Resource, die der Worker exklusiv hält
2. WaitHandle, das darüber Auskunft gibt, ob der Worker mit seiner exklusiven Arbeit fertig ist.

Folgender Beispielcode simuliert Dein Szenario unter Verwendung einer Semaphore, die den Zugriff auf die exklusive Resource steuert und einem WaitHandle, das die Beendigung des WorkerThreads anzeigt.

class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Example();
}

Semaphore workerResource = new Semaphore(1, 1); // single resource
AutoResetEvent workerFinished = new AutoResetEvent(false);

void Example()
{
Thread worker = new Thread(WorkerThreadFunc);
Thread monitor = new Thread(MonitoringThreadFunc);

worker.Start();
monitor.Start();

worker.Join();
monitor.Join();
workerResource.Close();
workerFinished.Close();
}

void WorkerThreadFunc()
{
Thread.Sleep(TimeSpan.FromMilliseconds(15));
workerResource.WaitOne();

//Work Starts
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(TimeSpan.FromMilliseconds(1000));
}
// Work Finished
Console.WriteLine("Worker finished (in worker thread)");
workerResource.Release();
workerFinished.Set();
}

void MonitoringThreadFunc()
{
while (!workerFinished.WaitOne(TimeSpan.FromMilliseconds(1000)))
{
Console.WriteLine("Still waiting for worker to finish...");
}
Console.WriteLine("Worker finished (in monitoring thread)");
}
}


Ich hoffe, das hilft Dir weiter.
Viel Erfolg,
Florian
11.10.2011
ffordermaier 8,4k 3 9
So funktionierts, danke...
danielw 12.10.2011
Hab den Code nochmal überarbeitet. Semaphore wurde nicht released und die Handles nicht aufgeräumt.
ffordermaier 12.10.2011

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH