Wednesday, October 05, 2005

Event raising issue

Few days back I was going thru an article on event raising in .NET environment and came accords a question " what is best the practice of raising event in multiple thread application" , let me illustrate with an example ...

say I have an delegate < public delegate void MyDelegate( Object sender, EventArgs e ); >
and an event < public event MyDelegate MyEvent; > inside a class named TestClass
I am raising event from a routine named RaiseEvent (Let me write the code snippet for this routine )

public void RaiseEvent()
{
if( MyEvent != null )
{
EventArgs e = new EventArgs();
MyEvent( this, e );
}
}

The above code will work fine in single thread environment, consider the following situation ... there are multiple threads which are using MyEvent( and there is single instance of TestClass is shared among all the threads ) , so it may happen( hypothetically ) when one thread is calling MyEvent( this, e ) another thread is removing the registered delegate from the MyEvent, have a look at the following figure ....

thread1 ...
action 1 : objTestClass.MyEvent -= new MyDelegate(objTestClass_MyEvent); ( removing the registered delegate from the MyEvent )

thread2 ...
action 1: if( MyEvent != null )
action 2: MyEvent( this, e );

If CPU switching between threads happen like the following, then there is a problem ..

thread2 -> action 1
thread1 -> action 1
thread2 -> action2 ( will raise an exception since the registered delegate from the MyEvent is removed ).

How to solve this issue .. firstly, I think we should not allow any thread to remove the registered delegate, if it is inevitable then how about the next solution
MyDelegate tmpMyEvent = MyEvent;

if( tmpMyEvent != null )
{
EventArgs e = new EventArgs();
tmpMyEvent( this, e );
}

This will solve the issue( am I correct ? ). I was looking for some MS documentation in this regards, but in vain , anybody has some comments to add .. please do.( thanks in advance -:) )











No comments: