Inleiding
Ik heb een probleem en ik kom er niet helemaal uit-- anders hadden jullie mij natuurlijk hier niet gezien. Misschien dat iemand met wat meer threading ervaring mij uit de boot kan helpen.
Wat is het probleem
Een typisch producer/consumer probleem met 1 uitzondering en dat is dat ik niet weet hoeveel consumers er zijn. Nu begrijp ik dat je met een AutoResetEvent netjes alle consumers kan laten wachten met WaitOne tot de producer een Set doet en dus 1 van de consumers verder laat gaan. (Dit klopt ... toch?)
Waar ik niet helemaal uit kom is een goede manier om een OnThreadingDone event uit te sturen als alle workers klaar zijn met werken. Dus niet als 1 thread klaar is maar allen.
Hoe?
Ik heb even wat code in elkaar geknutseld die het probleem (problemen) heel duidelijk demonstreren. Onderstaande code raakt zelfs in een deadlock hoewel het mij ontgaat waarom dit zo is. The OnDone, wat je hier niet ziet, doet gewoon een If this.InvokeRequired and veranderd het forum label om aan te geven dat alle workers klaar zijn.
Mijn vraag (vragen?)
Ik heb een probleem en ik kom er niet helemaal uit-- anders hadden jullie mij natuurlijk hier niet gezien. Misschien dat iemand met wat meer threading ervaring mij uit de boot kan helpen.
Wat is het probleem
Een typisch producer/consumer probleem met 1 uitzondering en dat is dat ik niet weet hoeveel consumers er zijn. Nu begrijp ik dat je met een AutoResetEvent netjes alle consumers kan laten wachten met WaitOne tot de producer een Set doet en dus 1 van de consumers verder laat gaan. (Dit klopt ... toch?)
Waar ik niet helemaal uit kom is een goede manier om een OnThreadingDone event uit te sturen als alle workers klaar zijn met werken. Dus niet als 1 thread klaar is maar allen.
Hoe?
Ik heb even wat code in elkaar geknutseld die het probleem (problemen) heel duidelijk demonstreren. Onderstaande code raakt zelfs in een deadlock hoewel het mij ontgaat waarom dit zo is. The OnDone, wat je hier niet ziet, doet gewoon een If this.InvokeRequired and veranderd het forum label om aan te geven dat alle workers klaar zijn.
Mijn vraag (vragen?)
- Hoe maak je een signaling mechanisme wat netjes werkt als -alle- threads klaar zijn. Ie: ik wil een event op het einde hebben.
- Wat doe ik nog meer fout hier?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
| delegate void OnDone (object sender, EventArgs e); delegate void OnAborted(object sender, EventArgs e); class ThreadMaster { private Thread masterThread; private readonly object threadLock; public event OnDone Done; public event OnAborted Aborted; public void threadCore(object data) { var e = (ManualResetEvent) data; try { var r = new Random(); Thread.Sleep(r.Next(5) * 1000); } finally { e.Set(); } } public void startThreadsAsync() { var threads = new Thread[7]; var events = new ManualResetEvent[7]; for (var i = 0; i < 7; i++) { threads[i] = new Thread(new ParameterizedThreadStart(threadCore)) {Name = "Slave thread"}; events[i] = new ManualResetEvent(false); threads[i].Start(events[i]); } try { WaitHandle.WaitAll(events); if ((Done != null)) Done.Invoke(this, new EventArgs()); lock (threadLock) masterThread = null; } catch (ThreadAbortException) { foreach (var t in threads) t.Abort(); WaitHandle.WaitAll(events); if ((Aborted != null)) Aborted.Invoke(this, new EventArgs()); lock (threadLock) masterThread = null; } } public void Abort() { lock (threadLock) { if (masterThread != null) masterThread.Abort(); } } public void StartThreads() { lock (threadLock) { if (masterThread != null) return; masterThread = new Thread(new ThreadStart(startThreadsAsync)); masterThread.Start(); } } public ThreadMaster() { threadLock = new object(); } } |
[ Voor 33% gewijzigd door bimm op 19-12-2008 20:29 . Reden: Even een klein iets repareren in mijn post. ]
Ik ook, jij niet?