<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Photoquarium Blog &#187; .Net</title>
	<atom:link href="http://blog.photoquarium.com/category/tech/dot_net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.photoquarium.com</link>
	<description>A bit of everything and anything that I find interesting</description>
	<lastBuildDate>Fri, 06 Feb 2009 18:37:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Thread safe EventHandling in C#</title>
		<link>http://blog.photoquarium.com/2008/03/25/thread-safe-eventhandling-in-c/</link>
		<comments>http://blog.photoquarium.com/2008/03/25/thread-safe-eventhandling-in-c/#comments</comments>
		<pubDate>Wed, 26 Mar 2008 04:22:41 +0000</pubDate>
		<dc:creator>Lucus Crawford</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thechniques]]></category>

		<guid isPermaLink="false">http://blog.photoquarium.com/2008/03/25/thread-safe-eventhandling-in-c/</guid>
		<description><![CDATA[I ran into a little issue with trying to update a UI from a working thread. I was working on refactoring some code which I took from .Net 1.1 and upgraded it to .Net 2.0 as well as refactoring some of my earlier work. Code that I now look at at slap myself trying to [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into a little issue with trying to update a UI from a working thread. I was working on refactoring some code which I took from .Net 1.1 and upgraded it to .Net 2.0 as well as refactoring some of my earlier work. Code that I now look at at slap myself trying to figure out why I had put all the business logic directly into the UI class. Dumb me. But that is all part of the learning process and I  don&#8217;t know anyone that writes code they are satisfied with when looking back on it a few days, months or years down the road.</p>
<p>Alright, enough of a side track back to the threading issue. Basically in the .Net 1.1 land you had to declare a a delegate and then create a instance of that delegate and then use that instance in your thread to do the actual updating. It can get quite messy. At least from my perspective. Here is a small example:</p>
<pre lang="c#">
     public class UI
     {
        public delegate void UpdateProgressBarDelegate(int percent);
        public UpdateProgressBarDelegate updateProgress;

        public UI()
       {
           updateProgress = new UpdateProgressBarDelegate(incrementProgressbar);
       }
    }</pre>
<p>Now in a function somewhere on the working thread  you would have this:</p>
<pre lang="c#">
     private class doingTheUpdate(int percent)
     {
         mainUI = updateProgress.Invoke(new object() { percent });
     }</pre>
<p>With .Net 2.0 it gets a bit simplified and you can use the EventHandler class to create an event and you don&#8217;t have to declare the delegate and then create an instance. Below is an example:</p>
<pre lang="c#">
    public class MyUI
    {
       public event EventHandler<myeventargs> UpdateProgressEvent;

       public void InvokeUpdateEvent(int percent)
       {
          InvokeUpdateEvent(UpdateProgressEvent, percent)
       }

       [MethodImpl(MethodImplOptions.NoInlining)]
       private void InvokeUpdateEvent(EventHandler<myeventargs> handler, int percent)
       {
          if( handler != null )
          {
             MyEventArgs e = new MyEventArgs(percent);
             handler.BeginInvoke(this, e, null, null);
          }
       }
   }
</myeventargs></myeventargs></pre>
<p>Now doesn&#8217;t that seem a bit more concise. I admit I am doing some other things there to help make this thread safe and I got most of this from <a href="http://davebrooks.wordpress.com/" target="_blank">Dave Brook&#8217;s</a> at <a href="http://davebrooks.wordpress.com/2007/02/07/threading-through-the-open-window-of-opportunity/" target="_blank">Aliens ate my GUI</a>. So I will try to summarize what it is doing.<br />
First where it looks like I am declaring the method InvokeUpdateEvent twice, once as public and once as private, I am. The reason this is done is because you can get a race condition if you just check for null and then call the event. A way to fix this potential race conditions Dave explains it very well so I won&#8217;t try.</p>
<blockquote><p><font size="2"> &#8220;One counter measure is to make a copy of the delegate. Delegates are immutable so by copying it to a temporary variable you keep a copy of the original state of the delegate, irrespective of any thread context switches. Making any change to the state of the delegate creates a new one on the heap and updates the reference to which the delegate point.&#8221;</font></p></blockquote>
<p>As well on the private InvokeUpdateEvent declaration there is a attribute added. This is added because the JIT compiler might optimize the code above and basically get you back to the state before where the race condition can occur. So the [MethodImpl(MethodImplOptions.NoInlining)] attribute is used to tell the <a href="http://en.wikipedia.org/wiki/Just-in-time_compilation" target="_blank">JIT</a> not to optimize this function.</p>
<p>The only other item in there is MyEventArgs class. This would just be a class that inherits from the EventArgs class and adds any info that needs to be sent with the event. In this example it was just the percent to update a progressbar.</p>
<p>Hope this helps. I know it helped me.</p>
<p><strong> Edit: </strong></p>
<p>Well I have jumped the gun a bit on this one and it looks like I needed to add one more thing to this to make it work on threads. when I call the event in the last function I still will need a BeginInvoke to make sure that it is run on the correct thread or else I get a cross threaded exception thrown. I have edited the code above to reflect this.</p>
<p>Also if you have any suggestions to improve this please post a comment. I am not perfect even though I tell myself I am.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.photoquarium.com/2008/03/25/thread-safe-eventhandling-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
