C # Multithreading and Events

Source: Internet
Author: User
Tags volatile

Original (C # multithreading and Events): http://www.codeproject.com/Articles/886223/Csharp-Multithreading-and-Events

The ' s ' start off with there are no perfectly safe multithreaded event handling as there are caveats/conditions that Mu St be handled. So it's really if the particular method you are in for the uses your require.

There is a great the article here:

Http://www.codeproject.com/Articles/37474/Threadsafe-Events

The one suggested solution the author mentions is don ' t use events in a multithreaded way. This can is a good solution when possible.)

I ' m going to show there be another problem to contend with and I'll offer some classes to help handle some scenarios s propose some alternative options you could use, but it depends in if your events can be used to that way. Ultimately it depends on what for you need to did, and Implementation/use and the complexity to wish. The Problems

To-start let's define the types of multithreading problems that come up and trying to solve this problem:possible Deadlo Cks Adding and removing event due to lock (the) or lock (type) for static events Race condition calling a null event a add Ed (subscribed) event handler is isn't immediately called A removed (unsubscribed) event handler is still. Deadlocks trying to subscribe/unsubscribe might don't get the most recent list of delegates to fire problem/feature-events Could be fired to delegates out of sequence

The general consensus is there isn't way to solve all of these issues. Perhaps but maybe let ' s to the ways we can work with these issues. Problem Details Problem #1 Possible deadlocks Adding and removing events

This should isn't to a problem in recent versions the. NET 4.5 is reportedly using lockfree constructs then should avoid this Type of issue. If you are need to handle this in earlier versions your could implement your own add/remove handlers with your own lock object To avoid some potential for deadlock scenario ' s. Problem #2 Race condition calling a null event

The problem is a even by default are null until you add a handler to it. If One thread is trying to add as another was trying to raise the event, or the last handler was trying to unsubscribe, when You are try to call the event you could get a null reference exception. Problem #3 An added event handler are not immediately called

In this scenario one thread adds a handler, but an event gets raised in the middle and this handler ' t doesn to be I Mmediately called.

So either controlling your event source are needed, not needing to worry much about a missed event, or you would need Hing more like "a message" the replayed events that already happened before subscribing. Problem #4 An event handler are removed but it is still called

In this scenario one thread removes a handler but the event is raised on another thread while this is happening and it stil L gets called even after it is thought to have unsubscribed. Problem #5 deadlock due to the event calling a handler that interacts and another thread that Subscribes/unsubscribes

In this scenario it causes a deadlock because if the event mechanism holds a lock while subscribing or Unsubscribing and W Hile calling events It might is possible to deadlock. (The article for more detailshttp://www.codeproject.com/articles/37474/threadsafe-events) Problem #6 might the most recent list of delegates to fire

We'll be in the recommended solution that's the code tries to take a copy of the delegate event list to fire. When it does this it's possible it might not get the most recent list because that another thread already updated the list . This might isn't be ' the big of ' an issue it's similar to problem #3 in, the net result is a added event subscription m Ight not receive a notification immediately after subscribing Problem/feature #7 delegates might receive events out O F Sequence Due

Note:this is more of a issue with the publisher of events controlling event ordering properly.

This can happen if multiple threads fire events at the same time, it possible they can appear to the subscriber out of T He expected sequence if there is an expected sequence. Once you have decided that multiple threads can fire events this could happen in anytime with even proper, one locking EAD beats another to firing a event so it appears. A slight variation #7 (B) of this are where the list of delegates starts to get one event sent to the list and then gets Ther event sent to it even before the ' the ' the ' the ' the ' the ' the ' the ' the ' the ' full list. If you are really wanted multithreaded events you might consider this a feature to truly support. Many events do have a typical order. Such as Got Focus, Lost Focus, session start, sessions end (either indicated with EventArgs in your event or via separate E Vents for each of those). The safest way to avoid it to always fire your events from one thread if this matters and/or control the controller T Hat decides onFiring events with multithreaded synchronization to avoid it sourcing multiple events at the same. So this problem would exist in the any multithreaded scenario where and isn't done. Since Those are actions need to being controlled by the publisher likely and some type of state management This is not cover Ed here.

(At the "End of" the article an example are shown of how to address event ordering between two events where the sequence Matt ERs

We can exclude problem #1 since as mentioned it is not really a issue anymore. Problem #3 As mentioned almost all implementations'll have unless your control your source of events/timing or implement Your events like a message bus to send new subscribes all of the previous events. The. NET events typically aren ' t used that way. Example of the basic problem multithreading issue for events Hide Copy Code

public Thiseventhandler thisevent;  Protected virtual onthisevent (Thiseventargs args) {If (thisevent!=null) thisevent (This,args); Thisevent could be null so for could get a null reference exception} 
Problem
#2 Null Exception race condition X
#3 A New subscriber might not get called immediately X
#4 A handler is still called after unsubscribe. X
#5 Possible Deadlock
#6 might most recent list of delegates to fire
#7 Problem/feature-events could is fired to delegates out of sequence X
normally recommended solution

Let's start with the recommended solution to understand what it handles and what it doesn ' t. Hide Copy Code

Public Thiseventhandler thisevent;

protected virtual void Onthisevent (Thiseventargs args)
{
   Thiseventhandler thisevent=thisevent;  Assign the event to a local variable
   If (thisevent!=null)
   {
      thisevent (This,args);
   }
Solution Summary

This solves problem #2 and does is not have problem #5

This has problems: #3 and #4. Which is so if you add a new handler it might don't get called immediately and if you remove a handler it could still get CA Lled for a short time. Better at least, we got rid of one problem. We also the solution introduces a possible #6 issue, it takes a copy of the list of handlers in the local thisevent V Ariable But because this variable are not volatile it may not get the most recent copy of the handler list.

Problem
#2 Null Exception race condition
#3 A New subscriber might not get called immediately X
#4 A handler is still called after unsubscribe. X
#5 Possible Deadlock
#6 might most recent copy of handlers to call X
#7 Problem/feature-events could is fired to delegates out of sequence X

One way can workaround problem #3 (adding a new handler–it doesn ' t get called immediately) (if possible) are to add Y Our handlers early before it are likely that multiple threads would be calling event. This avoids issues with #3.

For #4 the are unsubscribing set a bool flag that your event handler can check to the if it is being unsubscribed. If it is doing nothing. Or just have smart handling in your the event handler to know when this has happened. The problem is there are no safe way to doing this without locking.

Let ' s = if we can do better: Example Fix for normally recommended solution (publisher)

In the event Publisher if we use this code:hide Copy code

volatile thiseventhandler _localevent = null;
           Need volatile to ensure we ' latest public virtual void onthisevent (EventArgs args) {  _localevent=thisevent; Assign the event to a local variable –
           Notice is volatile class field if (_localevent!=null) {_localevent (This,args); }
        }

When isn't using locks in the event Publisher, notice the variable _localevent many examples for you might ' on the Internet s Ave a copy of the event into a variable and then call it if not NULL. They typically don ' t use a class volatile field. They should otherwise They might is getting copy. The "net effect may" is "much of" issue using a class field vs a local variable as it would generally is expected When a is called this local variable would be initialized at least once. In C # Local variables can ' t is volatile though, so to ensure reads/writes are directed to memory a volatile class field CA n be used. Example Improvement for the subscriber #1

In the event Subscriber class if we use This:hide Shrink Copy Code

private Object _lock = new Object ();

private volatile bool _unsubscribed=false;
                
       	private void Methodtounsubscribe () {lock (_lock) {_unsubscribed = true;
	Thisevent-= new Thiseventhandler (thiseventchanged);
                
            } public void Subscribe () {lock (_lock) {_unsubscribed = false;
       Thisevent + = new Thiseventhandler (thiseventchanged);
       	}//event handler private void Thiseventchanged (object sender, Thiseventargs e) {lock (_lock) { if (!_unsubscribed) {//do work here}}} 
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.