<?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>Quantum Bit Designs &#187; DelegateMarshaler</title>
	<atom:link href="http://blog.quantumbitdesigns.com/tag/delegatemarshaler/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.quantumbitdesigns.com</link>
	<description>Multithreading, WPF, .NET and Software Designs</description>
	<lastBuildDate>Tue, 26 Jan 2010 15:17:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>DelegateMarshaler &#8211; Replace Control.InvokeRequired and Control.Invoke</title>
		<link>http://blog.quantumbitdesigns.com/2008/07/22/delegatemarshaler-replace-controlinvokerequired-and-controlinvoke/</link>
		<comments>http://blog.quantumbitdesigns.com/2008/07/22/delegatemarshaler-replace-controlinvokerequired-and-controlinvoke/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 03:44:06 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[DelegateMarshaler]]></category>
		<category><![CDATA[Design]]></category>

		<guid isPermaLink="false">http://blog.quantumbitdesigns.com/?p=33</guid>
		<description><![CDATA[This is the third visitation of the topic of UI and worker thread interaction. Based upon excellent feedback through the comments (thanks Peter Ritchie and others) I have renamed and modified the previous ThreadBarrier implementation (which was a poor name to begin with since a thread barrier concept already represents something else). The previous pattern [...]]]></description>
			<content:encoded><![CDATA[<p><!--StartFragment -->This is the third visitation of the topic of UI and worker thread interaction. Based upon excellent feedback through the comments (thanks <a href="http://msmvps.com/Blogs/PeterRitchie/">Peter Ritchie</a> and others) I have renamed and modified the previous ThreadBarrier implementation (which was a poor name to begin with since a thread barrier concept already represents something else). The previous pattern of encapsulating a thread and communicating to the UI via events raised on the UI thread is still my recommendation: see the <a href="http://blog.quantumbitdesigns.com/2008/07/22/stop-polluting-the-ui-thread-use-a-delegatemarshaler/">first post</a> for a long winded explanation, and the <a href="http://blog.quantumbitdesigns.com/2008/07/22/simplifying-ui-and-worker-threads-delegatemarshaler-revisited/">second post</a> for more examples. However, there are many people that already have existing code that uses the Control.InvokeRequired and Control.Invoke pattern such as:</p>
<p style="margin: 0px"><span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> <span style="color: #2b91af;">UpdateProgressDelegate</span>(<span style="color: #0000ff;">int</span> progress);</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> UpdateProgressBar(<span style="color: #0000ff;">int</span> progress)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.InvokeRequired == <span style="color: #0000ff;">false</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.progressBarDownload.Value = progress;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.Invoke(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">UpdateProgressDelegate</span>(UpdateProgressBar), <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">object</span>[] { progress });</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p>The new implementation is intended to replace this code and support the original ThreadBarrier concept.</p>
<p><big><big><span style="font-weight: bold">Introducing the DelegateMarshaler</span><br style="font-weight: bold" /></big></big><br />
The DelegateMarshaler implementation is virtually identical to the ThreadBarrier except for four minor differences:</p>
<ol>
<li>The marshaler is created using a static method DelegateMarshaler.Create() so an exception can be thrown if no SynchronizationContext exists (console app, or before UI is started, etc.)</li>
<li>If the calling thread is already the target thread (UI thread), then the delegate is invoked normally rather than a cross thread invoke. This is similar to InvokeRequired being false.</li>
<li>The DelegateMarshaler supports methods with 0 to 4 arguments.</li>
<li>Static methods wrap ThreadPool.QueueUserWorkItem in a type safe way.</li>
</ol>
<p><strong>A compact example</strong></p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> buttonDownload_Click(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">DelegateMarshaler</span> marshaler = <span style="color: #2b91af;">DelegateMarshaler</span>.Create();</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #2b91af;">DelegateMarshaler</span>.QueueOnThreadPoolThread(</p>
<p style="margin: 0px">(fileName) =&gt;</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #008000;">//simulate download</span></p>
<p style="margin: 0px"><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 100; ++i)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">marshaler.Invoke(UpdateProgressBar, i);</p>
<p style="margin: 0px"><span style="color: #2b91af;">Thread</span>.Sleep(50);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">marshaler.Invoke(ShowDownloadComplete, fileName);</p>
<p style="margin: 0px">},</p>
<p style="margin: 0px"><span style="color: #a31515;">&#8220;somefile.txt&#8221;</span>);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> UpdateProgressBar(<span style="color: #0000ff;">int</span> progress)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.progressBarDownload.Value = progress;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> ShowDownloadComplete(<span style="color: #0000ff;">string</span> fileName)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelFileDownload.Text = fileName;</p>
<p style="margin: 0px">}</p>
<p>Using the DelegateMarshaler consists of creating the marshaler on the UI thread and invoking the methods that update the UI (preferably from the worker thread). Invoke will call the method synchronously, and BeginInvoke will call the method asynchronously allowing the worker to continue running while the UI updates. If your thread is a separate method altogether (which is usually the case), you would want to save the DelegateMarshaler instance as a private field in your form or control so it can be used in the thread method.</p>
<p><big><big><span style="font-weight: bold">The DelegateMarshaler Implementation</span></big></big></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">sealed</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">DelegateMarshaler</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">SynchronizationContext</span> _synchronizationContext;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #2b91af;">DelegateMarshaler</span> Create()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">SynchronizationContext</span>.Current == <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>(<span style="color: #a31515;">&#8220;No SynchronizationContext exists for the current thread.&#8221;</span>);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">DelegateMarshaler</span>(<span style="color: #2b91af;">SynchronizationContext</span>.Current);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> DelegateMarshaler(<span style="color: #2b91af;">SynchronizationContext</span> synchronizationContext)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext = synchronizationContext;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">bool</span> IsMarshalRequired</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">get</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span>._synchronizationContext != <span style="color: #2b91af;">SynchronizationContext</span>.Current;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Invoke&lt;T&gt;(<span style="color: #2b91af;">Action</span>&lt;T&gt; action, T arg)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.IsMarshalRequired == <span style="color: #0000ff;">false</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #008000;">// already on the target thread, just invoke delegate directly</span></p>
<p style="margin: 0px">action(arg);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #008000;">// marshal the delegate call to the target thread</span></p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Send(<span style="color: #0000ff;">delegate</span> { action(arg); }, <span style="color: #0000ff;">null</span>);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #008000;">//simplifies use of threadpool so arguments do not need to be cast</span></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> QueueOnThreadPoolThread&lt;T&gt;(<span style="color: #2b91af;">Action</span>&lt;T&gt; action, T arg)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">ThreadPool</span>.QueueUserWorkItem(<span style="color: #0000ff;">delegate</span> { action(arg); });</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p>It is such a small class, feel free to modify it to fit your needs. Download the sample for the complete code and comments:</p>
<p><a href="http://www.quantumbitdesigns.com/blogposts/0020/files/DelegateMarshalerSample.zip"><span style="font-weight: bold">DelegateMarshalerSample</span></a></p>
<p><span style="font-weight: bold">Notable Links</span><br style="font-weight: bold" /><span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"><a href="http://thevalerios.net/matt/2008/05/a-type-safe-backgroundworker-wrapper/">http://thevalerios.net/matt/2008/05/a-type-safe-backgroundworker-wrapper/</a><br />
</span><span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"><a href="http://weblogs.asp.net/justin_rogers/articles/126345.aspx">http://weblogs.asp.net/justin_rogers/articles/126345.aspx</a><br />
</span><span style="font-size: 11pt; font-family: 'Calibri','sans-serif';"><a href="http://www.codeproject.com/KB/cs/AOPInvokeRequired.aspx">http://www.codeproject.com/KB/cs/AOPInvokeRequired.aspx</a></span></p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f24%2fdelegatemarshaler-replace-controlinvokerequired-and-controlinvoke%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f24%2fdelegatemarshaler-replace-controlinvokerequired-and-controlinvoke%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quantumbitdesigns.com/2008/07/22/delegatemarshaler-replace-controlinvokerequired-and-controlinvoke/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplifying UI and Worker Threads &#8211; DelegateMarshaler Revisited</title>
		<link>http://blog.quantumbitdesigns.com/2008/07/22/simplifying-ui-and-worker-threads-delegatemarshaler-revisited/</link>
		<comments>http://blog.quantumbitdesigns.com/2008/07/22/simplifying-ui-and-worker-threads-delegatemarshaler-revisited/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 03:41:44 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[DelegateMarshaler]]></category>
		<category><![CDATA[Design]]></category>

		<guid isPermaLink="false">http://blog.quantumbitdesigns.com/?p=30</guid>
		<description><![CDATA[Background
Update &#8211; ThreadBarrier was a poorly chosen name, use the latest DelegateMarshaler implementation instead.
Previously I introduced the ThreadBarrier pattern which describes a simple technique for allowing worker threads to easily and safely communicate with controls on the UI thread. The key points from the previous article are:
A worker thread is completely contained within a class [...]]]></description>
			<content:encoded><![CDATA[<p><big><big><span style="font-weight: bold">Background</span></big></big></p>
<p><strong>Update</strong> &#8211; ThreadBarrier was a poorly chosen name, use the latest <a href="http://blog.quantumbitdesigns.com/2008/07/22/delegatemarshaler-replace-controlinvokerequired-and-controlinvoke/">DelegateMarshaler</a> implementation instead.</p>
<p>Previously I introduced the <a href="http://blog.quantumbitdesigns.com/2008/07/22/stop-polluting-the-ui-thread-use-a-delegatemarshaler/">ThreadBarrier pattern</a> which describes a simple technique for allowing worker threads to easily and safely communicate with controls on the UI thread. The key points from the previous article are:</p>
<p>A worker thread is completely contained within a class (and any objects the class references)</p>
<ol>
<li>Events from this worker class are raised on the UI thread</li>
<li>A SynchronizationContext is used rather than Control.Invoke or Dispatcher.Invoke</li>
<li>The UI code does not have to worry about what thread is executing, it always assumes the UI thread (keeps code clean)</li>
<li>The ThreadBarrier needs to be created on a UI thread to capture the UI&#8217;s SynchronizationContext</li>
</ol>
<p>Today&#8217;s article is a revisitation of the pattern to demonstrate several ways the technique can be used, as well as describe the flaw in the previous implementation. Yesterday&#8217;s article on <a href="http://blog.quantumbitdesigns.com/2008/07/22/events-and-threads/">events and threads</a> provides an in depth background on the subtleties of events and multithreading. The contents of today&#8217;s post include:</p>
<ul>
<li>The New ThreadBarrier Code</li>
<li>Sample UI and Worker Classes</li>
<li>ThreadBarrier Technique #1: Subclassing an existing worker thread class</li>
<li>ThreadBarrier Technique #2: Using extension methods on a SynchronizationContext</li>
<li>ThreadBarrier Technique #3: Deriving from a ThreadBarrier</li>
<li>ThreadBarrier Technique #4: Creating an instance of a ThreadBarrier</li>
<li>ThreadBarrier Technique #5: Creating an adapter class to propagate events</li>
<li>The Original ThreadBarrier Implementation Flaw</li>
<li>ThreadBarrier FAQ</li>
</ul>
<p><a style="font-weight: bold" href="http://www.quantumbitdesigns.com/blogposts/0019/files/ThreadBarrierExamples.zip">Download the examples</a><span style="font-weight: bold">.</span></p>
<p><big><big><span style="font-weight: bold">The New ThreadBarrier Code<br />
</span></big></big><br />
<span style="font-weight: bold">.NET 2.0</span></p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 ThreadBarrier\par ??\cf0     \{\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  The ThreadBarrier's captured SynchronizationContext\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 private\cf0  \cf4 SynchronizationContext\cf0  _synchronizationContext;\par ??\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  Captures the current thread's SynchronizationContext\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 public\cf0  ThreadBarrier()\par ??        \{\par ??            \cf3 this\cf0 ._synchronizationContext = \cf4 AsyncOperationManager\cf0 .SynchronizationContext;\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Post&amp;lt;T&amp;gt;(T e, \cf4 Action\cf0 &amp;lt;T&amp;gt; raiseEventMethod)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 ._synchronizationContext == \cf3 null\cf0 )\par ??            \{\par ??                \cf4 ThreadPool\cf0 .QueueUserWorkItem(\cf3 delegate\cf0  \{ raiseEventMethod(e); \});\par ??            \}\par ??            \cf3 else\par ??\cf0             \{\par ??                \cf3 this\cf0 ._synchronizationContext.Post(\cf3 delegate\cf0  \{ raiseEventMethod(e); \}, \cf3 null\cf0 );\par ??            \}\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Send&amp;lt;T&amp;gt;(T e, \cf4 Action\cf0 &amp;lt;T&amp;gt; raiseEventMethod)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 ._synchronizationContext == \cf3 null\cf0 )\par ??            \{\par ??                raiseEventMethod(e);\par ??            \}\par ??            \cf3 else\par ??\cf0             \{\par ??                \cf3 this\cf0 ._synchronizationContext.Send(\cf3 delegate\cf0  \{ raiseEventMethod(e); \}, \cf3 null\cf0 );\par ??            \}\par ??        \}\par ??    \}} --></p>
<p style="font-size: 8pt; background: white 0% 50%; color: black; font-family: Courier New; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial"><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red128\green128\blue128;\red0\green128\blue0;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 ThreadBarrier\par ??\cf0     \{\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  The ThreadBarrier's captured SynchronizationContext\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 private\cf0  \cf4 SynchronizationContext\cf0  _synchronizationContext;\par ??\par ??        \cf5 ///\cf6  \cf5 &amp;lt;summary&amp;gt;\par ??\cf0         \cf5 ///\cf6  Captures the current thread's SynchronizationContext\par ??\cf0         \cf5 ///\cf6  \cf5 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf3 public\cf0  ThreadBarrier()\par ??        \{\par ??            \cf3 this\cf0 ._synchronizationContext = \cf4 AsyncOperationManager\cf0 .SynchronizationContext;\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Post&amp;lt;T&amp;gt;(\cf4 Action\cf0 &amp;lt;T&amp;gt; raiseEventMethod, T e)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 ._synchronizationContext == \cf3 null\cf0 )\par ??            \{\par ??                \cf4 ThreadPool\cf0 .QueueUserWorkItem(\cf3 delegate\cf0  \{ raiseEventMethod(e); \});\par ??            \}\par ??            \cf3 else\par ??\cf0             \{\par ??                \cf3 this\cf0 ._synchronizationContext.Post(\cf3 delegate\cf0  \{ raiseEventMethod(e); \}, \cf3 null\cf0 );\par ??            \}\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Send&amp;lt;T&amp;gt;(\cf4 Action\cf0 &amp;lt;T&amp;gt; raiseEventMethod, T e)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 ._synchronizationContext == \cf3 null\cf0 )\par ??            \{\par ??                raiseEventMethod(e);\par ??            \}\par ??            \cf3 else\par ??\cf0             \{\par ??                \cf3 this\cf0 ._synchronizationContext.Send(\cf3 delegate\cf0  \{ raiseEventMethod(e); \}, \cf3 null\cf0 );\par ??            \}\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ThreadBarrier</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">SynchronizationContext</span> _synchronizationContext;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> ThreadBarrier()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext = <span style="color: #2b91af;">AsyncOperationManager</span>.SynchronizationContext;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Post&lt;T&gt;(<span style="color: #2b91af;">Action</span>&lt;T&gt; raiseEventMethod, T e)</p>
<p style="margin: 0px"><span style="color: #0000ff;">where</span> T : <span style="color: #2b91af;">EventArgs</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>._synchronizationContext == <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">ThreadPool</span>.QueueUserWorkItem(<span style="color: #0000ff;">delegate</span> { raiseEventMethod(e); });</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(<span style="color: #0000ff;">delegate</span> { raiseEventMethod(e); }, <span style="color: #0000ff;">null</span>);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p>}</p>
<p><span style="font-weight: bold">.NET 3.5</span></p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16     \cf3 public\cf0  \cf3 static\cf0  \cf3 class\cf0  \cf4 ThreadBarrierExtensions\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  Post&amp;lt;T&amp;gt;(\cf3 this\cf0  \cf4 SynchronizationContext\cf0  synchronizationContext, \cf4 Action\cf0 &amp;lt;T&amp;gt; raiseEventMethod, T eventArgs)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (synchronizationContext == \cf3 null\cf0 )\par ??            \{\par ??                \cf4 ThreadPool\cf0 .QueueUserWorkItem((e) =&amp;gt; raiseEventMethod((T)e), eventArgs);\par ??            \}\par ??            \cf3 else\par ??\cf0             \{\par ??                synchronizationContext.Post((e) =&amp;gt; raiseEventMethod((T)e), eventArgs);\par ??            \}\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  Send&amp;lt;T&amp;gt;(\cf3 this\cf0  \cf4 SynchronizationContext\cf0  synchronizationContext, \cf4 Action\cf0 &amp;lt;T&amp;gt; raiseEventMethod, T eventArgs)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (synchronizationContext == \cf3 null\cf0 )\par ??            \{\par ??                raiseEventMethod(eventArgs);\par ??            \}\par ??            \cf3 else\par ??\cf0             \{\par ??                synchronizationContext.Send((e) =&amp;gt; raiseEventMethod((T)e), eventArgs);\par ??            \}\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ThreadBarrierExtensions</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Post&lt;T&gt;(<span style="color: #0000ff;">this</span> <span style="color: #2b91af;">SynchronizationContext</span> synchronizationContext, <span style="color: #2b91af;">Action</span>&lt;T&gt; raiseEventMethod, T eventArgs)</p>
<p style="margin: 0px"><span style="color: #0000ff;">where</span> T : <span style="color: #2b91af;">EventArgs</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (synchronizationContext == <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">ThreadPool</span>.QueueUserWorkItem((e) =&gt; raiseEventMethod((T)e), eventArgs);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">synchronizationContext.Post((e) =&gt; raiseEventMethod((T)e), eventArgs);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p>}</p>
<p>The use of an anonymous delegate can be used for either implementation. The .NET 3.5 version uses a lambda expression just to demonstrate an alternate way of invoking the action.</p>
<p><big><big><span style="font-weight: bold">Sample UI and Worker Classes</span></big></big></p>
<p>The sample UI and worker classes are very simple examples that will be the reference code for the techniques that follow. The UI code remains virtually unchanged throughout every technique which is ideal since it should not be concerned with threading:</p>
<p><span style="color: #ff0000;">These classes do not work together as is, they need a ThreadBarrier.</span></p>
<p><span style="font-weight: bold">Sample Worker Class</span></p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 WeatherChecker\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt; TemperatureChanged;\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt; HumidityChanged;\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt; WindChanged;\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  Stopped;\par ??\par ??        \cf3 private\cf0  \cf3 bool\cf0  _isStopRequested;\par ??        \cf3 private\cf0  \cf4 Random\cf0  _random;\par ??\par ??        \cf3 public\cf0  WeatherChecker()\par ??        \{\par ??            \cf3 this\cf0 ._isStopRequested = \cf3 false\cf0 ;\par ??\par ??            \cf5 //used for generating random weather information\par ??\cf0             \cf3 this\cf0 ._random = \cf3 new\cf0  \cf4 Random\cf0 ((\cf3 int\cf0 )\cf4 DateTime\cf0 .Now.Ticks);\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Start()\par ??        \{\par ??            \cf4 Thread\cf0  thread = \cf3 new\cf0  \cf4 Thread\cf0 (\cf3 new\cf0  \cf4 ThreadStart\cf0 (CheckWeather));\par ??            thread.IsBackground = \cf3 true\cf0 ; \cf5 //prevents thread from keeping app alive when app is closed\par ??\cf0             thread.Start();\par ??        \}\par ??\par ??        \cf3 private\cf0  \cf3 void\cf0  CheckWeather()\par ??        \{\par ??            \cf3 while\cf0  (\cf3 this\cf0 ._isStopRequested == \cf3 false\cf0 )\par ??            \{\par ??                OnTemperatureChanged(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(30f)));\par ??                OnWindChanged(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(15f)));\par ??                OnHumidityChanged(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(100f)));\par ??\par ??                \cf5 //Updates roughly 4 times per second\par ??\cf0                 \cf4 Thread\cf0 .Sleep(250);\par ??            \}\par ??\par ??            OnStopped(\cf4 EventArgs\cf0 .Empty);\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  RequestStop()\par ??        \{\par ??            \cf3 this\cf0 ._isStopRequested = \cf3 true\cf0 ;\par ??        \}\par ??\par ??        \cf3 private\cf0  \cf3 float\cf0  Rand(\cf3 float\cf0  max)\par ??        \{\par ??            \cf3 return\cf0  (\cf3 float\cf0 )\cf3 this\cf0 ._random.NextDouble() * max;\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnTemperatureChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .TemperatureChanged != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .TemperatureChanged(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnHumidityChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .HumidityChanged != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .HumidityChanged(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnWindChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .WindChanged != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .WindChanged(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnStopped(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .Stopped != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .Stopped(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">WeatherChecker</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; TemperatureChanged;</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; HumidityChanged;</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; WindChanged;</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span> Stopped;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">bool</span> _isStopRequested;</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">Random</span> _random;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> WeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._isStopRequested = <span style="color: #0000ff;">false</span>;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #008000;">//used for generating random weather information</span></p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._random = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Random</span>((<span style="color: #0000ff;">int</span>)<span style="color: #2b91af;">DateTime</span>.Now.Ticks);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Start()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">Thread</span> thread = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Thread</span>(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">ThreadStart</span>(CheckWeather));</p>
<p style="margin: 0px">thread.IsBackground = <span style="color: #0000ff;">true</span>; <span style="color: #008000;">//prevents thread from keeping app alive when app is closed</span></p>
<p style="margin: 0px">thread.Start();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> CheckWeather()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">this</span>._isStopRequested == <span style="color: #0000ff;">false</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">OnTemperatureChanged(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(30f)));</p>
<p style="margin: 0px">OnWindChanged(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(15f)));</p>
<p style="margin: 0px">OnHumidityChanged(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(100f)));</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #008000;">//Updates roughly 4 times per second</span></p>
<p style="margin: 0px"><span style="color: #2b91af;">Thread</span>.Sleep(250);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">OnStopped(<span style="color: #2b91af;">EventArgs</span>.Empty);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> RequestStop()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._isStopRequested = <span style="color: #0000ff;">true</span>;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">float</span> Rand(<span style="color: #0000ff;">float</span> max)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">return</span> (<span style="color: #0000ff;">float</span>)<span style="color: #0000ff;">this</span>._random.NextDouble() * max;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnTemperatureChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.TemperatureChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.TemperatureChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnHumidityChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.HumidityChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.HumidityChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnWindChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.WindChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.WindChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnStopped(<span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.Stopped != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.Stopped(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p><span style="font-weight: bold">Sample UI Class</span></p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs16     \cf3 public\cf0  \cf3 partial\cf0  \cf3 class\cf0  \cf4 Form1\cf0  : \cf4 Form\par ??\cf0     \{\par ??        \cf3 private\cf0  \cf4 ThreadBarrierWeatherChecker\cf0  _weatherChecker;\par ??\par ??        \cf3 public\cf0  Form1()\par ??        \{\par ??            InitializeComponent();\par ??        \}\par ??\par ??        \cf3 private\cf0  \cf3 void\cf0  buttonStart_Click(\cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .buttonStart.Enabled = \cf3 false\cf0 ;\par ??            \cf3 this\cf0 .buttonStop.Enabled = \cf3 true\cf0 ;\par ??\par ??            \cf3 this\cf0 ._weatherChecker = \cf3 new\cf0  \cf4 ThreadBarrierWeatherChecker\cf0 ();\par ??            \cf3 this\cf0 ._weatherChecker.TemperatureChanged += \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_TemperatureChanged);\par ??            \cf3 this\cf0 ._weatherChecker.HumidityChanged += \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_HumidityChanged);\par ??            \cf3 this\cf0 ._weatherChecker.WindChanged += \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_WindChanged);\par ??            \cf3 this\cf0 ._weatherChecker.Stopped += \cf3 new\cf0  \cf4 EventHandler\cf0 (_weatherChecker_Stopped);\par ??\par ??            \cf3 this\cf0 ._weatherChecker.Start();\par ??        \}\par ??\par ??        \cf3 private\cf0  \cf3 void\cf0  buttonStop_Click(\cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._weatherChecker.RequestStop();\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_TemperatureChanged(\cf3 object\cf0  sender, \cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .labelTemperature.Text = \cf4 String\cf0 .Format(\cf5 "\{0:F1\} C"\cf0 , e.Value);\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_HumidityChanged(\cf3 object\cf0  sender, \cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .labelHumidity.Text = \cf4 String\cf0 .Format(\cf5 "\{0:F0\}%"\cf0 , e.Value);\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_WindChanged(\cf3 object\cf0  sender, \cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .labelWind.Text = \cf4 String\cf0 .Format(\cf5 "\{0:F0\} mph"\cf0 , e.Value);\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_Stopped(\cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .buttonStop.Enabled = \cf3 false\cf0 ;\par ??            \cf3 this\cf0 .buttonStart.Enabled = \cf3 true\cf0 ;\par ??\par ??            \cf3 this\cf0 ._weatherChecker = \cf3 null\cf0 ;\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Form1</span> : <span style="color: #2b91af;">Form</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">WeatherChecker</span> _weatherChecker;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> Form1()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">InitializeComponent();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> buttonStart_Click(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStart.Enabled = <span style="color: #0000ff;">false</span>;</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStop.Enabled = <span style="color: #0000ff;">true</span>;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherChecker</span>();</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.TemperatureChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_TemperatureChanged);</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.HumidityChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_HumidityChanged);</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.WindChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_WindChanged);</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.Stopped += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>(_weatherChecker_Stopped);</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.Start();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> buttonStop_Click(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.RequestStop();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_TemperatureChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelTemperature.Text = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F1} C&#8221;</span>, e.Value);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_HumidityChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelHumidity.Text = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F0}%&#8221;</span>, e.Value);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_WindChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelWind.Text = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F0} mph&#8221;</span>, e.Value);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_Stopped(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStop.Enabled = <span style="color: #0000ff;">false</span>;</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStart.Enabled = <span style="color: #0000ff;">true</span>;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker = <span style="color: #0000ff;">null</span>;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p><big><big><span style="font-weight: bold">ThreadBarrier Technique #1: Subclassing an existing worker thread class</span></big></big></p>
<p>The two classes above are doing nothing special to communicate with on another. An attempt to use the two together would fail since the worker class is raising events on the worker thread which is not allowed to access controls on the UI thread. Amazingly using a ThreadBarrier in the following way causes all events from the worker class to be automatically raised on the UI thread:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 ThreadBarrierWeatherChecker\cf0  : \cf4 WeatherChecker\par ??\cf0     \{\par ??        \cf3 private\cf0  \cf4 ThreadBarrier\cf0  _threadBarrier;\par ??\par ??        \cf3 public\cf0  ThreadBarrierWeatherChecker()\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier = \cf3 new\cf0  \cf4 ThreadBarrier\cf0 ();\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnTemperatureChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(e, \cf3 base\cf0 .OnTemperatureChanged);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnWindChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(e, \cf3 base\cf0 .OnWindChanged);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnHumidityChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(e, \cf3 base\cf0 .OnHumidityChanged);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnStopped(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(e, \cf3 base\cf0 .OnStopped);\par ??        \}\par ??    \}} --></p>
<p style="font-size: 8pt; background: white 0% 50%; color: black; font-family: Courier New; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial"><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 ThreadBarrierWeatherChecker\cf0  : \cf4 WeatherChecker\par ??\cf0     \{\par ??        \cf3 private\cf0  \cf4 ThreadBarrier\cf0  _threadBarrier;\par ??\par ??        \cf3 public\cf0  ThreadBarrierWeatherChecker()\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier = \cf3 new\cf0  \cf4 ThreadBarrier\cf0 ();\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnTemperatureChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(\cf3 base\cf0 .OnTemperatureChanged, e);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnWindChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(\cf3 base\cf0 .OnWindChanged, e);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnHumidityChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(\cf3 base\cf0 .OnHumidityChanged, e);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  OnStopped(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier.Post(\cf3 base\cf0 .OnStopped, e);\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ThreadBarrierWeatherChecker</span> : <span style="color: #2b91af;">WeatherChecker</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">ThreadBarrier</span> _threadBarrier;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> ThreadBarrierWeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">ThreadBarrier</span>();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnTemperatureChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(<span style="color: #0000ff;">base</span>.OnTemperatureChanged, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnWindChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(<span style="color: #0000ff;">base</span>.OnWindChanged, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnHumidityChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(<span style="color: #0000ff;">base</span>.OnHumidityChanged, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnStopped(<span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(<span style="color: #0000ff;">base</span>.OnStopped, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p>That&#8217;s it! All it took was deriving from the worker class and posting the <span style="font-style: italic">method</span> that raises the events to the UI thread. The UI class should create an instance of <span style="color: #339999;">ThreadBarrierWeatherChecker</span> rather than <span style="color: #339999;">WeatherChecker</span>. This technique is handy if you do not own or can&#8217;t modify the code to the worker class.</p>
<p><big><big><span style="font-weight: bold">ThreadBarrier Technique #2: Using extension methods on a SynchronizationContext</span></big></big><br />
<span style="font-family: Courier New;"><br />
</span>This technique requires the developer to not only have access to the WeatherChecker code, but also capture the UI&#8217;s SynchronizationContext in the WeatherChecker&#8217;s constructor:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs16         \cf3 private\cf0  \cf4 SynchronizationContext\cf0  _synchronizationContext;\par ??\par ??        \cf3 private\cf0  \cf3 bool\cf0  _isStopRequested;\par ??        \cf3 private\cf0  \cf4 Random\cf0  _random;\par ??\par ??        \cf3 public\cf0  WeatherChecker()\par ??        \{\par ??            \cf3 this\cf0 ._synchronizationContext = \cf4 AsyncOperationManager\cf0 .SynchronizationContext;\par ??\par ??            \cf3 this\cf0 ._isStopRequested = \cf3 false\cf0 ;\par ??\par ??            \cf5 //used for generating random weather information\par ??\cf0             \cf3 this\cf0 ._random = \cf3 new\cf0  \cf4 Random\cf0 ((\cf3 int\cf0 )\cf4 DateTime\cf0 .Now.Ticks);\par ??        \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">SynchronizationContext</span> _synchronizationContext;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> WeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext = <span style="color: #2b91af;">AsyncOperationManager</span>.SynchronizationContext;</p>
<p style="margin: 0px">&#8230;</p>
<p style="margin: 0px">}</p>
<p>Raising events now uses the _synchronizationContext field and the ThreadBarrier extension method:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16                 \cf3 this\cf0 ._synchronizationContext.Post(OnTemperatureChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(30f)));\par ??                \cf3 this\cf0 ._synchronizationContext.Post(OnWindChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(15f)));\par ??                \cf3 this\cf0 ._synchronizationContext.Post(OnHumidityChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(100f)));} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(OnTemperatureChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(30f)));</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(OnWindChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(15f)));</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(OnHumidityChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(100f)));</p>
<p><big><big><span style="font-weight: bold">ThreadBarrier Technique #3: Deriving from a ThreadBarrier</span></big></big></p>
<p>Again if the developer is in full control of the worker class, all that it takes is deriving from a ThreadBarrier to inherit the method that provides the posting to the UI thread:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 WeatherChecker\cf0  : \cf4 ThreadBarrier\par ??} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">WeatherChecker</span> : <span style="color: #2b91af;">ThreadBarrier</span></p>
<p>Raising the events is now a matter of calling the Post method in the base ThreadBarrier class:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16                 Post(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(30f)), OnTemperatureChanged);\par ??                Post(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(15f)), OnWindChanged);\par ??                Post(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(100f)), OnHumidityChanged);} --><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16                 Post(OnTemperatureChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(30f)));\par ??                Post(OnWindChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(15f)));\par ??                Post(OnHumidityChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(100f)));} --></p>
<p style="margin: 0px">Post(OnTemperatureChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(30f)));</p>
<p style="margin: 0px">Post(OnWindChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(15f)));</p>
<p style="margin: 0px">Post(OnHumidityChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(100f)));</p>
<p>In order for the ThreadBarrier to work the WeatherChecker class needs to be created on the UI thread so the base ThreadBarrier class can capture the UI&#8217;s SynchronizationContext.</p>
<p><big><big><span style="font-weight: bold">ThreadBarrier Technique #4: Creating an instance of a ThreadBarrier</span></big></big></p>
<p>If deriving from a ThreadBarrier is not an option, just creating an instance of a ThreadBarrier will work as well. This implementation is similar to the extension method sample, but the ThreadBarrier instance will hide the capturing and storing of the SynchronizationContext. This technique also requires the WeatherChecker to be created on the UI thread.</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs16         \cf3 private\cf0  \cf4 ThreadBarrier\cf0  _threadBarrier;\par ??\par ??        \cf3 private\cf0  \cf3 bool\cf0  _isStopRequested;\par ??        \cf3 private\cf0  \cf4 Random\cf0  _random;\par ??\par ??        \cf3 public\cf0  WeatherChecker()\par ??        \{\par ??            \cf3 this\cf0 ._threadBarrier = \cf3 new\cf0  \cf4 ThreadBarrier\cf0 ();\par ??\par ??            \cf3 this\cf0 ._isStopRequested = \cf3 false\cf0 ;\par ??\par ??            \cf5 //used for generating random weather information\par ??\cf0             \cf3 this\cf0 ._random = \cf3 new\cf0  \cf4 Random\cf0 ((\cf3 int\cf0 )\cf4 DateTime\cf0 .Now.Ticks);\par ??        \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">ThreadBarrier</span> _threadBarrier;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> WeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">ThreadBarrier</span>();</p>
<p style="margin: 0px">&#8230;</p>
<p style="margin: 0px">}</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16                 \cf3 this\cf0 ._threadBarrier.Post(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(30f)), OnTemperatureChanged);\par ??                \cf3 this\cf0 ._threadBarrier.Post(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(15f)), OnWindChanged);\par ??                \cf3 this\cf0 ._threadBarrier.Post(\cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(100f)), OnHumidityChanged);} --><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16                 \cf3 this\cf0 ._threadBarrier.Post(OnTemperatureChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(30f)));\par ??                \cf3 this\cf0 ._threadBarrier.Post(OnWindChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(15f)));\par ??                \cf3 this\cf0 ._threadBarrier.Post(OnHumidityChanged, \cf3 new\cf0  \cf4 WeatherEventArgs\cf0 (Rand(100f)));} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(OnTemperatureChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(30f)));</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(OnWindChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(15f)));</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._threadBarrier.Post(OnHumidityChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(100f)));</p>
<p><big><big><span style="font-weight: bold">ThreadBarrier Technique #5: Creating an adapter class to propagate events</span></big></big></p>
<p>This technique should be a last resort for the scenario where you can&#8217;t derive from the worker class and you are unable to modify its code. Since an extra set of events need to be created and subscribed, it can be dangerous and lead to memory leaks if the handlers are not properly removed.</p>
<p><strong>Adapter Class</strong> (extra events removed for compactness)<br />
<!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16     \cf3 public\cf0  \cf3 class\cf0  \cf4 ThreadBarrierWeatherChecker\cf0  : \cf4 ThreadBarrier\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt; TemperatureChanged;\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt; HumidityChanged;\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt; WindChanged;\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  Stopped;\par ??\par ??        \cf3 private\cf0  \cf4 WeatherChecker\cf0  _weatherChecker;\par ??\par ??        \cf3 public\cf0  ThreadBarrierWeatherChecker()\par ??        \{\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Attach(\cf4 WeatherChecker\cf0  weatherChecker)\par ??        \{\par ??            \cf3 this\cf0 ._weatherChecker = weatherChecker;\par ??            \cf3 this\cf0 ._weatherChecker.TemperatureChanged += \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_TemperatureChanged);\par ??            \cf3 this\cf0 ._weatherChecker.WindChanged += \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_WindChanged);\par ??            \cf3 this\cf0 ._weatherChecker.HumidityChanged += \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_HumidityChanged);\par ??            \cf3 this\cf0 ._weatherChecker.Stopped += \cf3 new\cf0  \cf4 EventHandler\cf0 (_weatherChecker_Stopped);\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Detach()\par ??        \{\par ??            \cf3 this\cf0 ._weatherChecker.TemperatureChanged -= \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_TemperatureChanged);\par ??            \cf3 this\cf0 ._weatherChecker.WindChanged -= \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_WindChanged);\par ??            \cf3 this\cf0 ._weatherChecker.HumidityChanged -= \cf3 new\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 WeatherEventArgs\cf0 &amp;gt;(_weatherChecker_HumidityChanged);\par ??            \cf3 this\cf0 ._weatherChecker.Stopped -= \cf3 new\cf0  \cf4 EventHandler\cf0 (_weatherChecker_Stopped);\par ??            \cf3 this\cf0 ._weatherChecker = \cf3 null\cf0 ;\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_TemperatureChanged(\cf3 object\cf0  sender, \cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            Post(OnTemperatureChanged, e);\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_WindChanged(\cf3 object\cf0  sender, \cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            Post(OnWindChanged, e);\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_HumidityChanged(\cf3 object\cf0  sender, \cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            Post(OnHumidityChanged, e);\par ??        \}\par ??\par ??        \cf3 void\cf0  _weatherChecker_Stopped(\cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            Post(OnStopped, e);\par ??        \}\par ??\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnTemperatureChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .TemperatureChanged != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .TemperatureChanged(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnHumidityChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .HumidityChanged != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .HumidityChanged(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnWindChanged(\cf4 WeatherEventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .WindChanged != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .WindChanged(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnStopped(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (\cf3 this\cf0 .Stopped != \cf3 null\cf0 )\par ??            \{\par ??                \cf3 this\cf0 .Stopped(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ThreadBarrierWeatherChecker</span> : <span style="color: #2b91af;">ThreadBarrier</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; TemperatureChanged;</p>
<p style="margin: 0px">&#8230;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">WeatherChecker</span> _weatherChecker;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> ThreadBarrierWeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Attach(<span style="color: #2b91af;">WeatherChecker</span> weatherChecker)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker = weatherChecker;</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.TemperatureChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_TemperatureChanged);</p>
<p>&#8230;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Detach()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.TemperatureChanged -= <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_TemperatureChanged);</p>
<p style="margin: 0px">&#8230;</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker = <span style="color: #0000ff;">null</span>;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_TemperatureChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">Post(OnTemperatureChanged, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnTemperatureChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.TemperatureChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.TemperatureChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p>The adapter class needs to provide a way to attach and detach to an already existing WeatherChecker instance. If the instance is not detached, it will result in a memory leak (the adapter class will be kept alive).</p>
<p><big><big><span style="font-weight: bold">The Original ThreadBarrier Implementation Flaw</span></big></big></p>
<p>The first implementation of the ThreadBarrier used the event as a parameter:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs16         \cf3 protected\cf0  \cf3 void\cf0  PostEvent&amp;lt;T&amp;gt;(\cf4 EventHandler\cf0 &amp;lt;T&amp;gt; eventHandler, \cf3 object\cf0  sender, T eventArgs)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf5 //do not raise the event if none was provided\par ??\cf0             \cf3 if\cf0  (eventHandler == \cf3 null\cf0 )\par ??            \{\par ??                \cf3 return\cf0 ;\par ??            \}\par ??\par ??            \cf3 this\cf0 ._synchronizationContext.Post(\cf3 delegate\cf0  \{ eventHandler(\cf3 this\cf0 , eventArgs); \}, \cf3 null\cf0 );\par ??        \}\par ??} --></p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">void</span> PostEvent&lt;T&gt;(<span style="color: #2b91af;">EventHandler</span>&lt;T&gt; eventHandler, <span style="color: #0000ff;">object</span> sender, T eventArgs)</p>
<p style="margin: 0px"><span style="color: #0000ff;">where</span> T : <span style="color: #2b91af;">EventArgs</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #008000;">//do not raise the event if none was provided</span></p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (eventHandler == <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">return</span>;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(<span style="color: #0000ff;">delegate</span> { eventHandler(<span style="color: #0000ff;">this</span>, eventArgs); }, <span style="color: #0000ff;">null</span>);</p>
<p style="margin: 0px">}</p>
<p>The problem with this implementation is that the event handler delegate is copied when passed to the method. During execution of this method (which occurs on the worker thread) a UI thread could remove the original handler and dispose of the UI control. Since the method&#8217;s copy of the delegate will still get posted to the UI thread, the handler will be executed in the control&#8217;s code even though the control was already disposed. In other words, if the worker class is being used by multiple windows or controls that are opening and closing it could lead to this problem. See Problem #2 in the <a href="http://blog.quantumbitdesigns.com/2008/07/22/events-and-threads/">Events and Threads</a> post.</p>
<p><big><big><span style="font-weight: bold">ThreadBarrier FAQ</span></big></big></p>
<p><span style="font-weight: bold">Q</span>: <span style="font-style: italic">Why not just use AsynchOperationManager.SynchronizationContext in the base class for each method post?</span><br />
<span style="font-weight: bold">A</span>: Since the methods are originally called on the worker thread, it means the call to the AsynchOperationManager.SynchronizationContext static property will be made from the worker thread. It will thus return an &#8216;empty&#8217; SynchronizationContext. The call to the static property must be made on the UI and the SynchronizationContext must be &#8217;saved&#8217; so the worker can use it.</p>
<p><span style="font-weight: bold">Q</span>: <span style="font-style: italic">Why not just use SynchronizationContext.Current?</span><br />
<span style="font-weight: bold">A</span>: The static SynchronizationContext.Current returns null when called from a worker thread, while AsynchOperationManager.SynchronizationContext will at least return an empty SynchronizationContext so we at least have some context reference.</p>
<p><span style="font-weight: bold">Q</span>: <span style="font-style: italic">What is the difference between a ThreadBarrier and BackgroundWorker?</span><br />
<span style="font-weight: bold">A</span>: The BackgroundWorker must also be created on a UI thread. However, the BackgroundWorker does not provide an easy and transparent way (other than ReportProgress) to post events and data from the worker to the UI thread. A ThreadBarrier will support any kind of event since it uses generics.</p>
<p><span style="font-weight: bold">Q</span>: <span style="font-style: italic">Why not use WPF&#8217;s built in cross-thread binding support?</span><br />
<span style="font-weight: bold">A</span>: A ThreadBarrier can be used in combination with WPF&#8217;s cross-thread binding. The difference is that a ThreadBarrier (and events) allow arbitrary code in the UI to execute. Properties just represent data.</p>
<p><a style="font-weight: bold" href="http://www.quantumbitdesigns.com/blogposts/0019/files/ThreadBarrierExamples.zip">Download the examples</a><span style="font-weight: bold">.<br />
</span></p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f18%2fsimplifying-ui-and-worker-threads-threadbarrier-revisited%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f18%2fsimplifying-ui-and-worker-threads-threadbarrier-revisited%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quantumbitdesigns.com/2008/07/22/simplifying-ui-and-worker-threads-delegatemarshaler-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Events and Threads</title>
		<link>http://blog.quantumbitdesigns.com/2008/07/22/events-and-threads/</link>
		<comments>http://blog.quantumbitdesigns.com/2008/07/22/events-and-threads/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 03:36:52 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[DelegateMarshaler]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Threads]]></category>

		<guid isPermaLink="false">http://blog.quantumbitdesigns.com/?p=27</guid>
		<description><![CDATA[The purpose of this post is to provide not only a reference for events and multithreading, but also as a background for the fix to the ThreadBarrier pattern I previously introduced. The original ThreadBarrier implementation has a flaw (Problem #2 below). Rather than just posting the fix and not describing the problem in detail, I [...]]]></description>
			<content:encoded><![CDATA[<p><!--StartFragment -->The purpose of this post is to provide not only a reference for events and multithreading, but also as a background for the fix to the <a href="http://blog.quantumbitdesigns.com/2008/06/10/stop-polluting-the-ui-thread-use-a-threadbarrier/">ThreadBarrier pattern</a> I previously introduced. The original ThreadBarrier implementation has a flaw (Problem #2 below). Rather than just posting the fix and not describing the problem in detail, I think it is better to provide an analysis and thorough investigation into the bug so that we all can learn together about the subtleties involved in multithreading. Remember: <a href="http://www.randomtree.org/eric/techblog/2004/10/multithreading-is-hard.html">multithreading is hard</a>. Tomorrow I will revisit the ThreadBarrier pattern with the fix as well as new ideas on how to use it. Until then, the following post shows several solutions to various problems with events and multithreading. I can&#8217;t take credit for all of it; most of it has been covered already <a href="http://davebrooks.wordpress.com/2007/02/07/threading-through-the-open-window-of-opportunity/">here</a>, <a href="http://code.logos.com/blog/2008/05/events_and_threads_part_3.html">here</a>, and <a href="http://rodenbaugh.net/post/Defensive-Event-Publishing.aspx">here</a>.</p>
<p><big style="font-weight: bold"><big>Problem #1: Race condition while raising event</big></big></p>
<p>As long as your class is not intended to be thread-safe, it is best to implement events using the following well known pattern:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 private\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MyEvent;\par ??\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (MyEvent != \cf3 null\cf0 )\par ??            \{\par ??                MyEvent(\cf3 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MyEvent;</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (MyEvent != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                MyEvent(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p>However, this pattern is not safe for use in multithreaded scenarios. The reason is because between the check for null and the calling of the handler, code executing on another thread may remove the handler. The check for null will pass, but when the call to the handler is made, it may then be null which causes a NullReferenceException. To illustrate how this can happen, consider the following code execution example.</p>
<table border="1" cellPadding="2" cellSpacing="0" style="width: 800px; text-align: left">
<tr>
<td>UI Thread</td>
<td>Worker Thread</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (MyEvent != \cf3 null\cf0 )\par ??            \{} --></p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (MyEvent != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16 MyEvent -= \cf3 new\cf0  \cf4 EventHandler\cf0 (MyClass_MyEvent);} --></p>
<p style="margin: 0px">MyEvent -= <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyClass_MyEvent);</p>
</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;}??\fs16                 MyEvent(\cf3 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">                MyEvent(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
</td>
<td> </td>
</tr>
</table>
<p><big style="font-weight: bold"><big>Solution 1.A</big></big></p>
<p>One solution is to make a copy of the event delegate before performing the check for null:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf4 EventHandler\cf0  eventHandler = \cf3 this\cf0 .MyEvent;\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(\cf3 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #2b91af">EventHandler</span> eventHandler = <span style="color: blue">this</span>.MyEvent;</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p>Since delegates are immutable, when the same UI/Worker code execution sequence occurs, the eventHandler copy will never be affected no matter how or when handlers are added or removed from MyEvent:</p>
<table border="1" cellPadding="2" cellSpacing="0" style="width: 800px; text-align: left">
<tr>
<td>UI Thread</td>
<td>Worker Thread</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf4 EventHandler\cf0  eventHandler = \cf3 this\cf0 .MyEvent;\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{} --></p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #2b91af">EventHandler</span> eventHandler = <span style="color: blue">this</span>.MyEvent;</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16 MyEvent -= \cf3 new\cf0  \cf4 EventHandler\cf0 (MyClass_MyEvent);} --></p>
<p style="margin: 0px">MyEvent -= <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyClass_MyEvent);</p>
</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;}??\fs16                 \cf3 //eventHandler will never change even \par ??\cf0                 \cf3 //if handlers are removed to added to MyEvent\par ??\cf0                 eventHandler(\cf4 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">                <span style="color: green">//eventHandler will never change even </span></p>
<p style="margin: 0px">                <span style="color: green">//if handlers are removed to added to MyEvent</span></p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
</td>
<td> </td>
</tr>
</table>
<p><big style="font-weight: bold"><big>Solution 1.B</big></big></p>
<p>According to various blog posts, there is a potential problem with solution 1.A. According to <a href="http://code.logos.com/blog/2008/05/events_and_threads_part_3.html">this post</a>, <a href="http://www.amazon.com/Programming-NET-Components-Juval-Lowy/dp/0596102070">Juval Lowy</a> claims JIT compiler inlining may eliminate the copy and bring us back to the original problem. The solution is to raise the event in another method and use the attribute MethodImplOptions.NoInlining. Since passing the event to the method effectively makes a copy for us, we do not need to make another copy in the method.</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            RaiseEvent(\cf3 this\cf0 .MyEvent, e);\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyGenericEvent(\cf4 MyEventArgs\cf0  e)\par ??        \{\par ??            RaiseEvent&amp;lt;\cf4 MyEventArgs\cf0 &amp;gt;(\cf3 this\cf0 .MyGenericEvent, e);\par ??        \}\par ??\par ??        [\cf4 MethodImpl\cf0 (\cf4 MethodImplOptions\cf0 .NoInlining)]\par ??        \cf3 private\cf0  \cf3 void\cf0  RaiseEvent(\cf4 EventHandler\cf0  eventHandler, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??\par ??        [\cf4 MethodImpl\cf0 (\cf4 MethodImplOptions\cf0 .NoInlining)]\par ??        \cf3 private\cf0  \cf3 void\cf0  RaiseEvent&amp;lt;T&amp;gt;(\cf4 EventHandler\cf0 &amp;lt;T&amp;gt; eventHandler, T e)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(\cf3 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            RaiseEvent(<span style="color: blue">this</span>.MyEvent, e);</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyGenericEvent(<span style="color: #2b91af">MyEventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            RaiseEvent&lt;<span style="color: #2b91af">MyEventArgs</span>&gt;(<span style="color: blue">this</span>.MyGenericEvent, e);</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        [<span style="color: #2b91af">MethodImpl</span>(<span style="color: #2b91af">MethodImplOptions</span>.NoInlining)]</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">void</span> RaiseEvent(<span style="color: #2b91af">EventHandler</span> eventHandler, <span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        [<span style="color: #2b91af">MethodImpl</span>(<span style="color: #2b91af">MethodImplOptions</span>.NoInlining)]</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">void</span> RaiseEvent&lt;T&gt;(<span style="color: #2b91af">EventHandler</span>&lt;T&gt; eventHandler, T e)</p>
<p style="margin: 0px">            <span style="color: blue">where</span> T : <span style="color: #2b91af">EventArgs</span></p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p>If we are using .NET 3.5 or higher we can create a single extension method to do all of this work for us:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16     \cf3 public\cf0  \cf3 static\cf0  \cf3 class\cf0  \cf4 EventExtensions\par ??\cf0     \{\par ??        [\cf4 MethodImpl\cf0 (\cf4 MethodImplOptions\cf0 .NoInlining)]\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  RaiseEvent(\cf3 this\cf0  \cf4 EventHandler\cf0  eventHandler, \cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(sender, e);\par ??            \}\par ??        \}\par ??\par ??        [\cf4 MethodImpl\cf0 (\cf4 MethodImplOptions\cf0 .NoInlining)]\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  RaiseEvent&amp;lt;T&amp;gt;(\cf3 this\cf0  \cf4 EventHandler\cf0 &amp;lt;T&amp;gt; eventHandler, \cf3 object\cf0  sender, T e)\par ??            \cf3 where\cf0  T : \cf4 EventArgs\par ??\cf0         \{\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(sender, e);\par ??            \}\par ??        \}\par ??    \}} --></p>
<p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">class</span> <span style="color: #2b91af">EventExtensions</span></p>
<p style="margin: 0px">    {</p>
<p style="margin: 0px">        [<span style="color: #2b91af">MethodImpl</span>(<span style="color: #2b91af">MethodImplOptions</span>.NoInlining)]</p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> RaiseEvent(<span style="color: blue">this</span> <span style="color: #2b91af">EventHandler</span> eventHandler, <span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(sender, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        [<span style="color: #2b91af">MethodImpl</span>(<span style="color: #2b91af">MethodImplOptions</span>.NoInlining)]</p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> RaiseEvent&lt;T&gt;(<span style="color: blue">this</span> <span style="color: #2b91af">EventHandler</span>&lt;T&gt; eventHandler, <span style="color: blue">object</span> sender, T e)</p>
<p style="margin: 0px">            <span style="color: blue">where</span> T : <span style="color: #2b91af">EventArgs</span></p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(sender, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">    }</p>
<p>Now raising events becomes very easy:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 private\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MyEvent;\par ??        \cf3 private\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0 &amp;lt;\cf4 MyEventArgs\cf0 &amp;gt; MyGenericEvent;\par ??\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .MyEvent.RaiseEvent(\cf3 this\cf0 , e);\par ??        \}\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyGenericEvent(\cf4 MyEventArgs\cf0  e)\par ??        \{\par ??            \cf3 this\cf0 .MyGenericEvent.RaiseEvent&amp;lt;\cf4 MyEventArgs\cf0 &amp;gt;(\cf3 this\cf0 , e);\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MyEvent;</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span>&lt;<span style="color: #2b91af">MyEventArgs</span>&gt; MyGenericEvent;</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent.RaiseEvent(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyGenericEvent(<span style="color: #2b91af">MyEventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyGenericEvent.RaiseEvent&lt;<span style="color: #2b91af">MyEventArgs</span>&gt;(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">        }</p>
<p><big><big><span style="font-weight: bold">Problem #2: Raising an event causes handler to execute in a disposed object</span></big></big></p>
<p>Now we are getting into the subtle areas of multithreading. This is an important scenario to understand because even though it may seem unlikely, it is actually quite easy to get bitten by this bug. To keep things simple, we will use the 1.A solution for the demonstration. The problem can occur when a listener on the UI thread removes its handler and is disposed, all before the worker thread calls the handler copy. This problem is not limited to a worker/UI thread scenario, it exists for any scenario where multiple threads are adding or removing event handlers.</p>
<p><span style="color: red">SideNote: Event handlers are always executed on the thread that raised them, not the thread that added or removed the handler. For example, A UI control could start 10 worker threads where each worker adds an event handler. If the UI thread raises the event, all 10 handlers will execute on the UI thread.</span></p>
<p>To demonstrate problem #2, consider the following user control:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs16     \cf3 public\cf0  \cf3 partial\cf0  \cf3 class\cf0  \cf4 MyUserControl\cf0  : \cf4 UserControl\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MyEvent;\par ??\par ??        \cf3 public\cf0  MyUserControl()\par ??        \{\par ??            InitializeComponent();\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  DemonstrateEventRaisedWhenDisposed()\par ??        \{\par ??            \cf3 this\cf0 .MyEvent += \cf3 new\cf0  \cf4 EventHandler\cf0 (MyUserControl_MyEvent);\par ??            \cf3 new\cf0  \cf4 Thread\cf0 (() =&amp;gt; OnMyEvent(\cf4 EventArgs\cf0 .Empty)).Start();\par ??            \cf3 this\cf0 .MyEvent -= \cf3 new\cf0  \cf4 EventHandler\cf0 (MyUserControl_MyEvent);\par ??            Dispose();\par ??        \}\par ??\par ??        \cf3 void\cf0  MyUserControl_MyEvent(\cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf5 //do something with the UI here\par ??\cf0         \}\par ??\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf4 EventHandler\cf0  eventHandler = \cf3 this\cf0 .MyEvent;\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(\cf3 this\cf0 , e);\par ??            \}\par ??        \}\par ??    \}\par ??} --></p>
<p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">partial</span> <span style="color: blue">class</span> <span style="color: #2b91af">MyUserControl</span> : <span style="color: #2b91af">UserControl</span></p>
<p style="margin: 0px">    {</p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MyEvent;</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">public</span> MyUserControl()</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            InitializeComponent();</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> DemonstrateEventRaisedWhenDisposed()</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent += <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyUserControl_MyEvent);</p>
<p style="margin: 0px">            <span style="color: blue">new</span> <span style="color: #2b91af">Thread</span>(() =&gt; OnMyEvent(<span style="color: #2b91af">EventArgs</span>.Empty)).Start();</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent -= <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyUserControl_MyEvent);</p>
<p style="margin: 0px">            Dispose();</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">void</span> MyUserControl_MyEvent(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: green">//do something with the UI here</span></p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #2b91af">EventHandler</span> eventHandler = <span style="color: blue">this</span>.MyEvent;</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">    }</p>
<p>If you are not familiar with lambda expressions, basically what is happening is that when DemonstrateEventRaisedWhenDisposed is called:</p>
<ol>
<li>An event handler is added to MyEvent</li>
<li>A thread is started that will call OnMyEvent which raises MyEvent</li>
<li>The previously added event handler from MyEvent is removed</li>
<li>The control is disposed</li>
</ol>
<p>Since there is no guarantee when the thread will start and execute, the code could execute in a safe way such as:</p>
<table border="1" cellPadding="2" cellSpacing="0" style="width: 900px; text-align: left">
<tr>
<td>UI Thread</td>
<td>Worker Thread</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 public\cf0  \cf3 void\cf0  DemonstrateEventRaisedWhenDisposed()\par ??        \{\par ??            \cf3 this\cf0 .MyEvent += \cf3 new\cf0  \cf4 EventHandler\cf0 (MyUserControl_MyEvent);\par ??            \cf3 this\cf0 .MyEvent -= \cf3 new\cf0  \cf4 EventHandler\cf0 (MyUserControl_MyEvent);} --></p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> DemonstrateEventRaisedWhenDisposed()</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent += <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyUserControl_MyEvent);</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent -= <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyUserControl_MyEvent);</p>
</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf4 EventHandler\cf0  eventHandler = \cf3 this\cf0 .MyEvent;\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{\par ??                eventHandler(\cf3 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #2b91af">EventHandler</span> eventHandler = <span style="color: blue">this</span>.MyEvent;</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;}??\fs16             Dispose();\par ??        \}\par ??} --></p>
<p style="margin: 0px">            Dispose();</p>
<p style="margin: 0px">        }</p>
</td>
<td> </td>
</tr>
</table>
<p>In this scenario, the event will not be raised by the worker thread, therefore the control will safely dispose and nothing bad will happen. But all it takes is some bad timing and a few context switches by the OS to expose the problem:</p>
<table border="1" cellPadding="2" cellSpacing="0" style="width: 1000px; text-align: left">
<tr>
<td>UI Thread</td>
<td>Worker Thread</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 public\cf0  \cf3 void\cf0  DemonstrateEventRaisedWhenDisposed()\par ??        \{\par ??            \cf3 this\cf0 .MyEvent += \cf3 new\cf0  \cf4 EventHandler\cf0 (MyUserControl_MyEvent);} --></p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> DemonstrateEventRaisedWhenDisposed()</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent += <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyUserControl_MyEvent);</p>
</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf4 EventHandler\cf0  eventHandler = \cf3 this\cf0 .MyEvent;\par ??            \cf3 if\cf0  (eventHandler != \cf3 null\cf0 )\par ??            \{} --></p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #2b91af">EventHandler</span> eventHandler = <span style="color: blue">this</span>.MyEvent;</p>
<p style="margin: 0px">            <span style="color: blue">if</span> (eventHandler != <span style="color: blue">null</span>)</p>
<p style="margin: 0px">            {</p>
</td>
</tr>
<tr>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16             \cf3 this\cf0 .MyEvent -= \cf3 new\cf0  \cf4 EventHandler\cf0 (MyUserControl_MyEvent);\par ??            Dispose();\par ??        \}} --></p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent -= <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyUserControl_MyEvent);</p>
<p style="margin: 0px">            Dispose();</p>
<p style="margin: 0px">        }</p>
</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;}??\fs16                 eventHandler(\cf3 this\cf0 , e);} --></p>
<p style="margin: 0px">                eventHandler(<span style="color: blue">this</span>, e);</p>
<p style="font-size: 8pt; background: white 0% 50%; color: black; font-family: Courier New; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial"><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs16                 \cf3 void\cf0  MyUserControl_MyEvent(\cf3 object\cf0  sender, \cf4 EventArgs\cf0  e)\par ??                \{\par ??                    \cf5 //two bad things: control is disposed, and we are\par ??\cf0                     \cf5 //executing on a worker thread in the control's code\par ??\cf0                 \}} --></p>
<p style="margin: 0px">                <span style="color: blue">void</span> MyUserControl_MyEvent(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">                {</p>
<p style="margin: 0px">                    <span style="color: green">//two bad things: control is disposed, and we are</span></p>
<p style="margin: 0px">                    <span style="color: green">//executing on a worker thread in the control&#8217;s code</span></p>
<p style="margin: 0px">                }</p>
</td>
</tr>
</table>
<p>All it took was the worker to pass the null check with the delegate copy, the UI thread removing the original handler then disposing, and then the worker calling the handler that was never removed from the copy. The MyUserControl_MyEvent method will effectively be executing in the UI control code (yet still on the worker thread; a post to the UI thread is needed to update the UI) even though the control has been disposed.</p>
<p><big style="font-weight: bold"><big>Solution 2.A</big></big></p>
<p>Unfortunately if we do not put any restrictions on which thread handles the events, there is little we can do to solve the problem. But if we constrain our requirements such that events must only be handled on the UI thread, we are able to come up with a relatively simple solution. The solution is to always call the OnXXX method on the UI thread. If a worker needs to raise the event, the worker should post the OnXXX method to the UI thread. This will guarantee that the handlers will never be called when null. This requirement also allows us to remove the need for the copy since we specified that worker threads will not be listening for the event. Using an extension method and the UI&#8217;s SynchronizationContext (for posting to the UI thread) gives the simple solution:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  PostExt&amp;lt;T&amp;gt;(\cf3 this\cf0  \cf4 SynchronizationContext\cf0  synchronizationContext, T eventArgs, \cf4 SendOrPostCallback\cf0  func)\par ??        \{\par ??            synchronizationContext.Post(func, eventArgs);\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> PostExt&lt;T&gt;(<span style="color: blue">this</span> <span style="color: #2b91af">SynchronizationContext</span> synchronizationContext, T eventArgs, <span style="color: #2b91af">SendOrPostCallback</span> func)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            synchronizationContext.Post(func, eventArgs);</p>
<p style="margin: 0px">        }</p>
<p>A call from a worker thread would use the UI&#8217;s synchronization context to post the OnXXXmethod to the UI thread for safely raising the event:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16             \cf3 new\cf0  \cf4 Thread\cf0 (() =&amp;gt;\par ??                synchronizationContext.PostExt(\cf4 EventArgs\cf0 .Empty, e =&amp;gt; OnMyEvent(\cf4 EventArgs\cf0 .Empty))\par ??                ).Start();} --></p>
<p style="margin: 0px">synchronizationContext.PostExt(<span style="color: #2b91af">EventArgs</span>.Empty, e =&gt; OnMyEvent(<span style="color: #2b91af">EventArgs</span>.Empty))</p>
<p>The synchronizationContext variable is the SynchronizationContext that was captured on the UI thread before the worker was started. For more information read the original <a href="http://blog.quantumbitdesigns.com/2008/06/10/stop-polluting-the-ui-thread-use-a-threadbarrier/">ThreadBarrier</a> article and stay tuned for tomorrow&#8217;s complete coverage and solution using this technique.</p>
<p><big style="font-weight: bold"><big>Solution 2.B</big></big></p>
<p>If our requirements are unconstrained and any object on any thread could be listening for events, we are in trouble. The only way to prevent the race condition is to lock around the event&#8217;s null check and handler call. However this is bad practice since it can lead to deadlocks (subject for another blog entry).</p>
<p><span style="color: red">Do not use this code:</span></p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 private\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MyEvent;\par ??        \cf3 private\cf0  \cf3 object\cf0  myEventObject = \cf3 new\cf0  \cf3 object\cf0 ();\par ??\par ??        \cf3 protected\cf0  \cf3 virtual\cf0  \cf3 void\cf0  OnMyEvent(\cf4 EventArgs\cf0  e)\par ??        \{\par ??            \cf3 lock\cf0  (myEventObject)\par ??            \{\par ??                \cf3 this\cf0 .MyEvent.RaiseEvent(\cf3 this\cf0 , e);\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MyEvent;</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">object</span> myEventObject = <span style="color: blue">new</span> <span style="color: blue">object</span>();</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">protected</span> <span style="color: blue">virtual</span> <span style="color: blue">void</span> OnMyEvent(<span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">lock</span> (myEventObject)</p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                <span style="color: blue">this</span>.MyEvent.RaiseEvent(<span style="color: blue">this</span>, e);</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p><big style="font-weight: bold"><big>Problem #3: Adding and removing of event handlers is not thread-safe by default</big></big></p>
<p>When a standard event is declared in a class and no Add/Remove accessors are explicitly defined, the C# 2.0+ compiler automatically make accesses to the event thread-safe. Consider the following standard event:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 private\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MyEvent;} --></p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MyEvent;</p>
<p>The compiler will automatically create thread-safe accessors:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;}??\fs16         [\cf3 MethodImpl\cf0 (\cf3 MethodImplOptions\cf0 .Synchronized)]\par ??        \cf4 private\cf0  \cf4 void\cf0  add_MyEvent(\cf3 EventHandler\cf0  value)\par ??        \{\par ??            \cf4 this\cf0 .MyEvent = (\cf3 EventHandler\cf0 )\cf3 Delegate\cf0 .Combine(\cf4 this\cf0 .MyEvent, value);\par ??        \}\par ??        [\cf3 MethodImpl\cf0 (\cf3 MethodImplOptions\cf0 .Synchronized)]\par ??        \cf4 private\cf0  \cf4 void\cf0  remove_MyEvent(\cf3 EventHandler\cf0  value)\par ??        \{\par ??            \cf4 this\cf0 .MyEvent = (\cf3 EventHandler\cf0 )\cf3 Delegate\cf0 .Remove(\cf4 this\cf0 .MyEvent, value);\par ??        \}} --></p>
<p style="margin: 0px">        [<span style="color: #2b91af">MethodImpl</span>(<span style="color: #2b91af">MethodImplOptions</span>.Synchronized)]</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">void</span> add_MyEvent(<span style="color: #2b91af">EventHandler</span> value)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent = (<span style="color: #2b91af">EventHandler</span>)<span style="color: #2b91af">Delegate</span>.Combine(<span style="color: blue">this</span>.MyEvent, value);</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px">        [<span style="color: #2b91af">MethodImpl</span>(<span style="color: #2b91af">MethodImplOptions</span>.Synchronized)]</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">void</span> remove_MyEvent(<span style="color: #2b91af">EventHandler</span> value)</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">this</span>.MyEvent = (<span style="color: #2b91af">EventHandler</span>)<span style="color: #2b91af">Delegate</span>.Remove(<span style="color: blue">this</span>.MyEvent, value);</p>
<p style="margin: 0px">        }</p>
<p>Unfortunately there is still a problem. When subscribing to the event in the following way:<br />
<!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16             MyEvent += \cf3 new\cf0  \cf4 EventHandler\cf0 (MyClass_MyEvent);} --></p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">            MyEvent += <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyClass_MyEvent);</p>
<p>The compiler will convert this to:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;}??\fs16             MyEvent = (\cf3 EventHandler\cf0 )\cf3 Delegate\cf0 .Combine(MyEvent, \cf4 new\cf0  \cf3 EventHandler\cf0 (MyClass_MyEvent));} --></p>
<p style="margin: 0px">            MyEvent = (<span style="color: #2b91af">EventHandler</span>)<span style="color: #2b91af">Delegate</span>.Combine(MyEvent, <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(MyClass_MyEvent));</p>
<p>This makes the operation not thread-safe. It is almost as if the compiler only went half way to thread safety. If we were to start two threads running in parallel both adding and removing a handler (only one is shown below):</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16             \cf3 int\cf0  numLoops = 10000000;\par ??            \cf4 Thread\cf0  thread1 = \cf3 new\cf0  \cf4 Thread\cf0 (() =&amp;gt; \{\par ??                \cf3 for\cf0  (\cf3 int\cf0  i = 0; i &amp;lt; numLoops; ++i)\par ??                \{\par ??                    \cf3 this\cf0 .MySafeEvent += \cf3 new\cf0  \cf4 EventHandler\cf0 (EventHandlerMethod);\par ??                    \cf3 this\cf0 .MySafeEvent -= \cf3 new\cf0  \cf4 EventHandler\cf0 (EventHandlerMethod);\par ??                \}\par ??            \});\par ??            thread1.IsBackground = \cf3 true\cf0 ;\par ??            thread1.Start();} --></p>
<p style="margin: 0px">            <span style="color: blue">int</span> numLoops = 10000000;</p>
<p style="margin: 0px">            <span style="color: #2b91af">Thread</span> thread1 = <span style="color: blue">new</span> <span style="color: #2b91af">Thread</span>(() =&gt; {</p>
<p style="margin: 0px">                <span style="color: blue">for</span> (<span style="color: blue">int</span> i = 0; i &lt; numLoops; ++i)</p>
<p style="margin: 0px">                {</p>
<p style="margin: 0px">                    <span style="color: blue">this</span>.MySafeEvent += <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(EventHandlerMethod);</p>
<p style="margin: 0px">                    <span style="color: blue">this</span>.MySafeEvent -= <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(EventHandlerMethod);</p>
<p style="margin: 0px">                }</p>
<p style="margin: 0px">            });</p>
<p style="margin: 0px">            thread1.IsBackground = <span style="color: blue">true</span>;</p>
<p style="margin: 0px">            thread1.Start();</p>
<p>If the adding and removing of the event were thread-safe, once both threads were complete the event should have zero handlers. Since the operation is not thread-safe, what happens is the event will have a few extra handlers due to races.</p>
<p><big style="font-weight: bold"><big>Solution 3</big></big><big style="font-weight: bold"><big>.A</big></big></p>
<p>If multiple threads need to add and remove handlers, the event should be designed using the following pattern:</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 private\cf0  \cf3 object\cf0  mySafeEventLock = \cf3 new\cf0  \cf3 object\cf0 ();\par ??        \cf3 private\cf0  \cf4 EventHandler\cf0  mySafeEventHandler;\par ??\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MySafeEvent\par ??        \{\par ??            \cf3 add\par ??\cf0             \{\par ??                \cf3 lock\cf0  (\cf3 this\cf0 .mySafeEventLock)\par ??                \{\par ??                    \cf3 this\cf0 .mySafeEventHandler += \cf3 value\cf0 ;\par ??                \}\par ??            \}\par ??            \cf3 remove\par ??\cf0             \{\par ??                \cf3 lock\cf0  (\cf3 this\cf0 .mySafeEventLock)\par ??                \{\par ??                    \cf3 this\cf0 .mySafeEventHandler -= \cf3 value\cf0 ;\par ??                \}\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">object</span> mySafeEventLock = <span style="color: blue">new</span> <span style="color: blue">object</span>();</p>
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: #2b91af">EventHandler</span> mySafeEventHandler;</p>
<p style="margin: 0px">&nbsp;</p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MySafeEvent</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">add</span></p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                <span style="color: blue">lock</span> (<span style="color: blue">this</span>.mySafeEventLock)</p>
<p style="margin: 0px">                {</p>
<p style="margin: 0px">                    <span style="color: blue">this</span>.mySafeEventHandler += <span style="color: blue">value</span>;</p>
<p style="margin: 0px">                }</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">            <span style="color: blue">remove</span></p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                <span style="color: blue">lock</span> (<span style="color: blue">this</span>.mySafeEventLock)</p>
<p style="margin: 0px">                {</p>
<p style="margin: 0px">                    <span style="color: blue">this</span>.mySafeEventHandler -= <span style="color: blue">value</span>;</p>
<p style="margin: 0px">                }</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p>The C# compiler will now make adding and removing handlers normal. This is code after compilation (identical to before compilation):</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16             MySafeEvent += \cf3 new\cf0  \cf4 EventHandler\cf0 (\cf3 this\cf0 .EventHandlerMethod);} --></p>
<p style="margin: 0px">            MySafeEvent += <span style="color: blue">new</span> <span style="color: #2b91af">EventHandler</span>(<span style="color: blue">this</span>.EventHandlerMethod);</p>
<p>However, the addition and removal of the event is converted (again this is post compilation):</p>
<p><!-- {\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs16         \cf3 public\cf0  \cf3 event\cf0  \cf4 EventHandler\cf0  MySafeEvent\par ??        \{\par ??            \cf3 add\par ??\cf0             \{\par ??                \cf3 lock\cf0  (\cf3 this\cf0 .mySafeEventLock)\par ??                \{\par ??                    \cf3 this\cf0 .mySafeEventHandler = (\cf4 EventHandler\cf0 )\cf4 Delegate\cf0 .Combine(\cf3 this\cf0 .mySafeEventHandler, \cf3 value\cf0 );\par ??                \}\par ??            \}\par ??            \cf3 remove\par ??\cf0             \{\par ??                \cf3 lock\cf0  (\cf3 this\cf0 .mySafeEventLock)\par ??                \{\par ??                    \cf3 this\cf0 .mySafeEventHandler = (\cf4 EventHandler\cf0 )\cf4 Delegate\cf0 .Remove(\cf3 this\cf0 .mySafeEventHandler, \cf3 value\cf0 );\par ??                \}\par ??            \}\par ??        \}} --></p>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">event</span> <span style="color: #2b91af">EventHandler</span> MySafeEvent</p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: blue">add</span></p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                <span style="color: blue">lock</span> (<span style="color: blue">this</span>.mySafeEventLock)</p>
<p style="margin: 0px">                {</p>
<p style="margin: 0px">                    <span style="color: blue">this</span>.mySafeEventHandler = (<span style="color: #2b91af">EventHandler</span>)<span style="color: #2b91af">Delegate</span>.Combine(<span style="color: blue">this</span>.mySafeEventHandler, <span style="color: blue">value</span>);</p>
<p style="margin: 0px">                }</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">            <span style="color: blue">remove</span></p>
<p style="margin: 0px">            {</p>
<p style="margin: 0px">                <span style="color: blue">lock</span> (<span style="color: blue">this</span>.mySafeEventLock)</p>
<p style="margin: 0px">                {</p>
<p style="margin: 0px">                    <span style="color: blue">this</span>.mySafeEventHandler = (<span style="color: #2b91af">EventHandler</span>)<span style="color: #2b91af">Delegate</span>.Remove(<span style="color: blue">this</span>.mySafeEventHandler, <span style="color: blue">value</span>);</p>
<p style="margin: 0px">                }</p>
<p style="margin: 0px">            }</p>
<p style="margin: 0px">        }</p>
<p>But since the handler update is happening inside the lock, the adds and removes are thread-safe. Click <a href="http://www.quantumbitdesigns.com/blogposts/0018/files/EventsAndThreadSafety.zip">here for a sample</a> that demonstrates both safe and unsafe event designs.</p>
<p><big style="font-weight: bold"><big>Conclusion</big></big></p>
<p>There are many mind bending scenarios involved when events are mixed with multithreading. It is best to try and keep things as simple as possible. Hopefully this post serves as a great reference for things to think about when designing your events, classes, and threads.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f17%2fevents-and-threads%2f"><img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f17%2fevents-and-threads%2f" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quantumbitdesigns.com/2008/07/22/events-and-threads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stop Polluting the UI Thread &#8211; Use a DelegateMarshaler</title>
		<link>http://blog.quantumbitdesigns.com/2008/07/22/stop-polluting-the-ui-thread-use-a-delegatemarshaler/</link>
		<comments>http://blog.quantumbitdesigns.com/2008/07/22/stop-polluting-the-ui-thread-use-a-delegatemarshaler/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 03:31:21 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[DelegateMarshaler]]></category>
		<category><![CDATA[Design]]></category>

		<guid isPermaLink="false">http://blog.quantumbitdesigns.com/?p=25</guid>
		<description><![CDATA[Introduction
Update &#8211; ThreadBarrier was a poorly chosen name, use the latest DelegateMarshaler implementation instead.
With the advent of multi-core processors becoming standard in desktop PCs, it is clear we are on the verge of a shift in which high level software is designed and developed. First there was Object Oriented programming, then design patterns, and now [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p><strong>Update</strong> &#8211; ThreadBarrier was a poorly chosen name, use the latest <a href="http://blog.quantumbitdesigns.com/2008/07/22/delegatemarshaler-replace-controlinvokerequired-and-controlinvoke/">DelegateMarshaler</a> implementation instead.</p>
<p>With the advent of multi-core processors becoming standard in desktop PCs, it is clear we are on the verge of a shift in which high level software is designed and developed. First there was Object Oriented programming, then design patterns, and now there is multithreading. Multithreading has been around for decades in high end computing, but due to the now wide availability of multiple cores in a standard PC or laptop, it is only now that it is beginning to gain mainstream attention. There is a lot of work to do for tools, frameworks, and patterns to simplify the design and debugging of multithreading programs. While Microsoft has been working diligently to improve their tools (Visual Studio) and frameworks (<a href="http://www.microsoft.com/downloads/details.aspx?familyid=348F73FD-593D-4B3C-B055-694C50D2B0F3&amp;displaylang=en">Task Parallel Library</a>) to bring multithreading into the mainstream, there is not yet enough guidance and information on the internet about proper threading techniques and design patterns.</p>
<p>This is where the ‘ThreadBarrier’ pattern comes in. Ultimately it is a way to help simplify the interaction between the UI and worker threads. A ThreadBarrier is an encapsulation of thread execution inside a class such that it is not exposed to the outside world. Rather, external events are first posted to the UI thread so any listener (on the UI thread) does not have to worry about threading issues. Like any pattern, there are times where it is ideal to use and there are times where it does not apply. Use at your own discretion.</p>
<p><strong>Background</strong></p>
<p>It seems that nearly every introductory threading example on the internet consists of a button click that starts a thread that performs some operation in a worker thread in the UI code behind. While simple examples are good, this immediately introduces a developer to starting threads In UI code and thinking that such techniques are normal.</p>
<p><strong>The Problem</strong></p>
<p>The problem is that the only way most developers know how to get data back to the UI thread is to use a UI control to post back the information. In case you are new to threading: the golden rule is that all UI controls (windows, textboxes, progressbars, etc.) can only be accessed from the thread that created them (the UI thread of course). This means a worker thread cannot do myTextBox.Text=”asdf” otherwise a cross-thread exception will be thrown. Controls provide a mechanism for executing a method on the UI thread (Control.Invoke, Control.BeginInvoke, Dispatcher.Invoke, Dispatcher.BeginInvoke).</p>
<p>WinForms example:</p>
<p style="margin: 0px"><span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> <span style="color: #2b91af;">SetStartDelegate</span>(<span style="color: #0000ff;">bool</span> enabled);</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> SetStartEnabled(<span style="color: #0000ff;">bool</span> enabled)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.InvokeRequired == <span style="color: #0000ff;">false</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStart.Enabled = enabled;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.Invoke(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">SetStartDelegate</span>(SetStartEnabled), <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">object</span>[] { enabled });</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p><!--EndFragment-->WPF example:</p>
<p style="margin: 0px"><span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> <span style="color: #2b91af;">SetStartDelegate</span>(<span style="color: #0000ff;">bool</span> enabled);</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> SetStartEnabled(<span style="color: #0000ff;">bool</span> enabled)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.Dispatcher.CheckAccess() == <span style="color: #0000ff;">true</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStart.IsEnabled = enabled;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.Dispatcher.Invoke(<span style="color: #2b91af;">DispatcherPriority</span>.Send, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">SetStartDelegate</span>(SetStartEnabled), enabled);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p><!--EndFragment-->There are tricks to make this a bit cleaner, but that is the common way to update the UI from any thread.</p>
<p>The combination of the Control’s UI thread rule and a Control’s ability to invoke on the UI thread essentially handcuffs developers into mixing threads with the UI and trying to make it work. Perhaps some have tried to be smart and hide the threads away deep in non-UI code to keep the UI clean. Those developers probably end up with the following questions (at least I did):</p>
<p>“How the heck do you get a control for invoking that deep in the execution and far away from the UI code? And more importantly, why does it have to be this way? There has to be a better way.”</p>
<p><strong>The Answer</strong></p>
<p>There is a better way, and it involves a <a href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx">SynchronizationContext</a>. Rather than use a Control to post execution back to the UI, a SynchronizationContext provides this same capability without the UI Control requirement. Since a fantastic CodeProject <a href="http://www.codeproject.com/KB/cpp/SyncContextTutorial.aspx">article</a> already covers the SynchronizationContext in depth, a summary will only be described here.</p>
<p><strong>SynchronizationContext Overview</strong></p>
<p>-SynchronizationContext is an abstract base class for:<br />
-WindowsFormsSynchronizationContext<br />
-DispatcherSynchronizationContext<br />
-WinForms automatically creates an instance of WindowsFomsSynchronizationContext for a WinForms UI thread.<br />
-WPF automatically creates an instance of DispatcherSynchronizationContext for a WPF UI thread.<br />
-Static property AsyncOperationManager.SynchronizationContext gets the SynchronizationContext for the calling thread: WindowsFormsSynchronizationContext in WinForms and DispatcherSynchronizationContext in WPF.<br />
-SynchronizationContext provides two methods (Send and Post) for synchronous or asynchronous method invocation.<br />
-Getting AsyncOperationManager.SynchronizationContext on a non-UI thread (such as in a console app or worker thread) returns the base SynchronizationContext class that just invokes a method on the calling thread when Send is used, and calls a method on a ThreadPool thread when Post is used.</p>
<p><strong>Introducing the ThreadBarrier ‘Pattern’</strong></p>
<p>The ThreadBarrier pattern consists of a non-UI class encapsulating and executing a worker thread and always raising its events on the UI thread using a SynchronizationContext. The worker thread execution should never leave the class via events. Data and objects within the class may be operated upon by the worker thread but all external events must be called on the UI thread. If this technique is correctly followed then the listening UI code does not need to worry about thread checks and delegate posting.</p>
<p><strong>Implementing a ThreadBarrier’ (.NET 2.0)</strong></p>
<p>A ThreadBarrier can be implemented as an abstract class so that derived classes automatically inherit the necessary functionality to support the pattern.</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">abstract</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ThreadBarrier</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">SynchronizationContext</span> _synchronizationContext;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> ThreadBarrier()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext = <span style="color: #2b91af;">AsyncOperationManager</span>.SynchronizationContext;</p>
<p style="margin: 0px">}</p>
<p><!--EndFragment-->The SyncronizationContext must be stored as a field so that it can be used by the worker thread in the derived class. Since the static AsyncOperationManager.SynchronizationContext property is called in the constructor, a critical requirement of properly using a ThreadBarrier derived class is that it must be created on the thread in which events want to be raised. In other words, create the class on the UI thread so that the UI’s context is captured. A worker thread can then use this context to post the methods that raise events back to the UI. The following protected method can be used for posting OnXXX methods:</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Post&lt;T&gt;(<span style="color: #2b91af;">Action</span>&lt;T&gt; raiseEventMethod, T e)</p>
<p style="margin: 0px"><span style="color: #0000ff;">where</span> T : <span style="color: #2b91af;">EventArgs</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>._synchronizationContext == <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">ThreadPool</span>.QueueUserWorkItem(<span style="color: #0000ff;">delegate</span> { raiseEventMethod(e); });</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(<span style="color: #0000ff;">delegate</span> { raiseEventMethod(e); }, <span style="color: #0000ff;">null</span>);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p><!--EndFragment--></p>
<p style="margin: 0px">For an event such as:</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span> Stopped;</p>
<p style="margin: 0px"><!--EndFragment--><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnStopped(<span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.Stopped != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.Stopped(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><!--EndFragment--><!--EndFragment--></p>
<p style="margin: 0px">A ThreadBarrier derived class simply posts events to the UI in this way:</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">Post(OnStopped, <span style="color: #2b91af;">EventArgs</span>.Empty);</p>
<p style="margin: 0px"><!--EndFragment--></p>
<p style="margin: 0px">A small example of a class implementing a ThreadBarrier would look like:</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">WeatherChecker</span> : <span style="color: #2b91af;">ThreadBarrier</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; TemperatureChanged;</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; HumidityChanged;</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt; WindChanged;</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> <span style="color: #2b91af;">EventHandler</span> Stopped;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">bool</span> _isStopRequested;</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">Random</span> _random;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> WeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._isStopRequested = <span style="color: #0000ff;">false</span>;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #008000;">//used for generating random weather information</span></p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._random = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Random</span>((<span style="color: #0000ff;">int</span>)<span style="color: #2b91af;">DateTime</span>.Now.Ticks);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Start()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">Thread</span> thread = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">Thread</span>(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">ThreadStart</span>(CheckWeather));</p>
<p style="margin: 0px">thread.IsBackground = <span style="color: #0000ff;">true</span>; <span style="color: #008000;">//prevents thread from keeping app alive when app is closed</span></p>
<p style="margin: 0px">thread.Start();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> CheckWeather()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">this</span>._isStopRequested == <span style="color: #0000ff;">false</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">Post(OnTemperatureChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(30f)));</p>
<p style="margin: 0px">Post(OnWindChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(15f)));</p>
<p style="margin: 0px">Post(OnHumidityChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(100f)));</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #008000;">//Updates roughly 4 times per second</span></p>
<p style="margin: 0px"><span style="color: #2b91af;">Thread</span>.Sleep(250);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">Post(OnStopped, <span style="color: #2b91af;">EventArgs</span>.Empty);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> RequestStop()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._isStopRequested = <span style="color: #0000ff;">true</span>;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">float</span> Rand(<span style="color: #0000ff;">float</span> max)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">return</span> (<span style="color: #0000ff;">float</span>)<span style="color: #0000ff;">this</span>._random.NextDouble() * max;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnTemperatureChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.TemperatureChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.TemperatureChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnHumidityChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.HumidityChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.HumidityChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnWindChanged(<span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.WindChanged != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.WindChanged(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnStopped(<span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.Stopped != <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.Stopped(<span style="color: #0000ff;">this</span>, e);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><!--EndFragment--><!--EndFragment--></p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">The key points are:<br />
-WeatherChecker derives from ThreadBarrier<br />
-The worker thread is started inside this non-UI WeatherChecker class.<br />
-The WeatherChecker should be created on the UI thread.</p>
<p>Now the UI code is very clean and does not have to worry about threads:</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Form1</span> : <span style="color: #2b91af;">Form</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">WeatherChecker</span> _weatherChecker;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> Form1()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">InitializeComponent();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> buttonStart_Click(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStart.Enabled = <span style="color: #0000ff;">false</span>;</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStop.Enabled = <span style="color: #0000ff;">true</span>;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherChecker</span>();</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.TemperatureChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_TemperatureChanged);</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.HumidityChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_HumidityChanged);</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.WindChanged += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>&lt;<span style="color: #2b91af;">WeatherEventArgs</span>&gt;(_weatherChecker_WindChanged);</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.Stopped += <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">EventHandler</span>(_weatherChecker_Stopped);</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.Start();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> buttonStop_Click(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.RequestStop();</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_TemperatureChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelTemperature.Text = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F1} C&#8221;</span>, e.Value);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_HumidityChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelHumidity.Text = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F0}%&#8221;</span>, e.Value);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_WindChanged(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">WeatherEventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelWind.Text = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F0} mph&#8221;</span>, e.Value);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"> </p>
<p><span style="overflow: hidden; width: 0px; position: absolute; height: 0px;"><a href="http://kvantservice.com/">????????</a></span></p>
<p style="margin: 0px"><span style="color: #0000ff;">void</span> _weatherChecker_Stopped(<span style="color: #0000ff;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStop.Enabled = <span style="color: #0000ff;">false</span>;</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.buttonStart.Enabled = <span style="color: #0000ff;">true</span>;</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker = <span style="color: #0000ff;">null</span>;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p><!--EndFragment--><strong>Implementing a ThreadBarrier (.NET 3.5)</strong></p>
<p>Since the requirement of deriving from a ThreadBarrier class is not ideal, in .NET 3.5 we can use extension methods to help us do the work.</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ThreadBarrierExtensions</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Post&lt;T&gt;(<span style="color: #0000ff;">this</span> <span style="color: #2b91af;">SynchronizationContext</span> synchronizationContext, <span style="color: #2b91af;">Action</span>&lt;T&gt; raiseEventMethod, T eventArgs)</p>
<p style="margin: 0px"><span style="color: #0000ff;">where</span> T : <span style="color: #2b91af;">EventArgs</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">if</span> (synchronizationContext == <span style="color: #0000ff;">null</span>)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #2b91af;">ThreadPool</span>.QueueUserWorkItem((e) =&gt; raiseEventMethod((T)e), eventArgs);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: #0000ff;">else</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">synchronizationContext.Post((e) =&gt; raiseEventMethod((T)e), eventArgs);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><!--EndFragment--><!--EndFragment--></p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">Now the WeatherChecker class does not have to derive from a ThreadBarrier (but it now has to do the work in its constructor of saving a reference to the SynchronizationContext, the task previously left for the abstract ThreadBarrier class).:</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">WeatherChecker</span></p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">SynchronizationContext</span> _synchronizationContext;</p>
<p style="margin: 0px"><span style="color: #0000ff;">&#8230;</span></p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">public</span> WeatherChecker()</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext = <span style="color: #2b91af;">AsyncOperationManager</span>.SynchronizationContext;</p>
<p style="margin: 0px"><span style="color: #0000ff;">&#8230;</span></p>
<p style="margin: 0px">}</p>
<p><!--EndFragment-->Using an extension method on the SynchronizationContext allows us to post the OnXXX method:</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._synchronizationContext.Post(OnTemperatureChanged, <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">WeatherEventArgs</span>(Rand(30f)));</p>
<p style="margin: 0px"><!--EndFragment--></p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">Using Lambda expressions also simplifies the handling of the events in the UI code:</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>._weatherChecker.TemperatureChanged += (weatherChecker, weatherEventArgs) =&gt;</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px"><span style="color: #0000ff;">this</span>.labelTemperature.Content = <span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">&#8220;{0:F1} C&#8221;</span>, weatherEventArgs.Value);</p>
<p style="margin: 0px">};</p>
<p><!--EndFragment--><strong>Conclusion</strong></p>
<p>The ThreadBarrier technique is an easy way to simplify the use of a worker thread and how it interacts with the UI. It is not the silver bullet for multithreading, but it does offer a way to think of a thread as an ‘object’ and hide the threading complexities. The UI and worker thread can be separated even further by designing a ThreadBarrier class to do nothing but handle events from other threading code (such as in a library that you do not have the code) and propagate just these events to the UI. This truly allows the business ‘logic’ to be free of any UI dependencies.</p>
<p><strong>Samples</strong></p>
<p><!--StartFragment --></p>
<li>ThreadBarrier Technique #1: Subclassing an existing worker thread class</li>
<li>ThreadBarrier Technique #2: Using extension methods on a SynchronizationContext</li>
<li>ThreadBarrier Technique #3: Deriving from a ThreadBarrier</li>
<li>ThreadBarrier Technique #4: Creating an instance of a ThreadBarrier</li>
<li>ThreadBarrier Technique #5: Creating an adapter class to propagate events</li>
<p><strong><a href="http://www.quantumbitdesigns.com/blogposts/0019/files/ThreadBarrierExamples.zip">Download all Samples</a></strong></p>
<p><strong>UPDATE:</strong> The DelegateMarshaler has been <a href="http://blog.quantumbitdesigns.com/2008/07/22/simplifying-ui-and-worker-threads-delegatemarshaler-revisited/">revisited</a> with a description of the 5 techniques in the sample.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f10%2fstop-polluting-the-ui-thread-use-a-threadbarrier%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.quantumbitdesigns.com%2f2008%2f06%2f10%2fstop-polluting-the-ui-thread-use-a-threadbarrier%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quantumbitdesigns.com/2008/07/22/stop-polluting-the-ui-thread-use-a-delegatemarshaler/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
