Ik ben tegen een in mijn ogen heel vreemd probleem aangelopen. Ik heb een class met wat events. Deze class wordt wat rondgeslingerd binnen mijn multi-threaded applicatie en andere classes gebruiken events van deze class. Nu werkt dit prima.
Totdat de maker thread van de class het object gaat locken, en andere threads vervolgens aan events willen koppelen van dit object. Het koppelen van het event duurt dan net zolang totdat de lock op het object met de events vrijgegeven wordt. Nu is de vraag: waarom?
Ik heb een heel simpel voorbeeldje gemaakt die het probleem illustreert:
Het gebruik van een anonymous method is trouwens niet de oorzaak.
/edit
De vraag is niet zozeer of dit een handige manier van aanpak is of hoe je dit kunt voorkomen, maar vooral waarom dit gedrag zich voordoet. Ik zie het event TestEvent namelijk gelijkwaardig aan een public field. Was het een integer die je ophoogt met += dan werkt het uiteraard wel.
Ik heb inmiddels het probleem omzeild wat de boel in mijn ogen ook logischer maakt, maar dan nog ben ik erg benieuwd naar het waarom.
Totdat de maker thread van de class het object gaat locken, en andere threads vervolgens aan events willen koppelen van dit object. Het koppelen van het event duurt dan net zolang totdat de lock op het object met de events vrijgegeven wordt. Nu is de vraag: waarom?
Ik heb een heel simpel voorbeeldje gemaakt die het probleem illustreert:
C#:
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
| using System; using System.Threading; namespace SandBox { class Person { public event EventHandler TestEvent; public Person() { } public void DoTestEvent() { if (TestEvent != null) TestEvent(this, EventArgs.Empty); } } class Program { public void Run() { Person person = new Person(); lock (person) { Thread thread = new Thread(new ParameterizedThreadStart(RunThread)); thread.Start(person); thread.Join(); } Console.ReadLine(); } private void RunThread(object parameter) { Console.WriteLine("Start thread."); Person person = (Person)parameter; // Hij blijft oneindig hangen op de volgende regel: person.TestEvent += delegate(object sender, EventArgs e) { Console.WriteLine("Test event fired."); }; Console.WriteLine("End thread."); } static unsafe void Main(string[] args) { new Program().Run(); } } } |
Het gebruik van een anonymous method is trouwens niet de oorzaak.
/edit
De vraag is niet zozeer of dit een handige manier van aanpak is of hoe je dit kunt voorkomen, maar vooral waarom dit gedrag zich voordoet. Ik zie het event TestEvent namelijk gelijkwaardig aan een public field. Was het een integer die je ophoogt met += dan werkt het uiteraard wel.
Ik heb inmiddels het probleem omzeild wat de boel in mijn ogen ook logischer maakt, maar dan nog ben ik erg benieuwd naar het waarom.
[ Voor 12% gewijzigd door Verwijderd op 19-10-2007 01:10 ]