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);
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);
//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