<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>jaredpar's WebLog : ISynchronizeInvoke</title><link>http://blogs.msdn.com/jaredpar/archive/tags/ISynchronizeInvoke/default.aspx</link><description>Tags: ISynchronizeInvoke</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>ISynchronizeInvoke ... now</title><link>http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx</link><pubDate>Tue, 08 Jan 2008 05:25:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7022839</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/7022839.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=7022839</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=7022839</wfw:comment><description>&lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.isynchronizeinvoke.aspx"&gt;ISynchronizeInvoke&lt;/a&gt; is an interface which allows you to execute a delegate synchronously or asynchronously.&amp;nbsp; The implementer of the interface can control how the delegate is executed.&amp;nbsp; In particular the implementer controls on which thread the delegate is executed.&amp;nbsp; &lt;/p&gt; &lt;p&gt;It's common for thread sensitive objects to implement this interface.&amp;nbsp; It allows consumers to execute long lived actions on a background thread and then use the ISynchronizeInvoke interface to get back onto the original thread.&amp;nbsp; System.Windows.Forms.Control is a great example of this usage pattern.&lt;/p&gt; &lt;p&gt;Several API's that I own are very thread aware and will often defer to a background thread for the completion of their operation.&amp;nbsp; It makes it easier to build UI on top of it.&amp;nbsp; They take an ISynchronizedInvoke as a parameter in order to properly signal the caller than an operation is completed.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The difficulty can come in testing it.&amp;nbsp; Many implementers of ISynchronizeInvoke use message pumping to implement the behavior.&amp;nbsp; As a result it's not always easy to use for testing (unit testing in particular).&amp;nbsp; To work around this I designed an implementation of ISynchronizeInvoke that does not rely on the message pumping but provides a completely compliant ISynchronizeInvoke implementation.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The idea is to just do it ... now.&amp;nbsp; I call the class ImmediateInvoke.&amp;nbsp; The basic methods are straight forward.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ISynchronizeInvoke&lt;/span&gt;.Invoke(&lt;span style="color: rgb(43,145,175)"&gt;Delegate&lt;/span&gt; method, &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt;[] args)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; method.DynamicInvoke(args);
        }

        &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ISynchronizeInvoke&lt;/span&gt;.InvokeRequired
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;; }
        }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The other two methods are a little more tricky.&amp;nbsp; The require an implementation of &lt;a href="http://msdn2.microsoft.com/en-us/library/system.iasyncresult.aspx"&gt;IAsyncResult&lt;/a&gt;.&amp;nbsp; The basic usage pattern is the consumer will call BeginInvoke, peform some operations and finally call EndInvoke when it wants to join with the asynchronous operation.&amp;nbsp; I will use the thread pool to perform this operation and define a private nested class for the IAsnycResult implementation called AsyncResult&lt;/p&gt;
&lt;p&gt;The implementation needs a few variables to implement the contract. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;m_handle - An implementation of ManualResetEvent to satisfy the AsyncWaitHandle property&lt;/li&gt;
&lt;li&gt;m_completed - A simple int to capture whether or not we have completed&lt;/li&gt;
&lt;li&gt;m_return - Return of the delegate&lt;/li&gt;
&lt;li&gt;m_exception - Exception thrown by calling the delegate.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Most of the properties are straight forward.&lt;/p&gt;&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt; AsyncState
            {
                &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;; }
            }

            &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; System.Threading.&lt;span style="color: rgb(43,145,175)"&gt;WaitHandle&lt;/span&gt; AsyncWaitHandle
            {
                &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_handle; }
            }

            &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; CompletedSynchronously
            {
                &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;; }
            }

            &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; IsCompleted
            {
                &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_completed == 1; }
            }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Now we need to define a method to run the delegate passed to BeginInvoke in the thread pool and update the state as we go along.&amp;nbsp; I call this method directly from the constructor.&lt;/p&gt;&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; RunDelegateAsync(&lt;span style="color: rgb(43,145,175)"&gt;Delegate&lt;/span&gt; method, &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt;[] args)
            {
                &lt;span style="color: rgb(43,145,175)"&gt;WaitCallback&lt;/span&gt; del = &lt;span style="color: rgb(0,0,255)"&gt;delegate&lt;/span&gt;(&lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt; unused)
                {
                    &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;                    {
                        &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt; temp = method.DynamicInvoke(args);
                        &lt;span style="color: rgb(43,145,175)"&gt;Interlocked&lt;/span&gt;.Exchange(&lt;span style="color: rgb(0,0,255)"&gt;ref&lt;/span&gt; m_return, temp);
                    }
                    &lt;span style="color: rgb(0,0,255)"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt; ex)
                    {
                        &lt;span style="color: rgb(43,145,175)"&gt;Interlocked&lt;/span&gt;.Exchange(&lt;span style="color: rgb(0,0,255)"&gt;ref&lt;/span&gt; m_exception, ex);
                    }

                    &lt;span style="color: rgb(43,145,175)"&gt;Interlocked&lt;/span&gt;.Exchange(&lt;span style="color: rgb(0,0,255)"&gt;ref&lt;/span&gt; m_completed, 1);
                    m_handle.Set();
                };

                &lt;span style="color: rgb(43,145,175)"&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem(del);
            }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Notice I've avoided using a lock in this implementation.&amp;nbsp; This is safe for this case.&amp;nbsp; All of the members are set atomically.&amp;nbsp; Only m_completed can be accessed before the operation is completed and it is simply checked for the value 1.&amp;nbsp; Since the value is set atomically this is safe.&amp;nbsp; In the implementation of EndInvoke I will not access any of the other variables until the WaitHandle is signaled and then I will not make any decision based on the contents of their values (rather the abscence or presence).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Also notice that I did not explicitly dispose of the WaitHandle.&amp;nbsp; This is a quirk of the ISynchronizeInvoke interface.&amp;nbsp; It specifies that callers of BeginInvoke must call EndInvoke and that the IAsyncResult must be valid until EndInvoke is called.&amp;nbsp; As such you can't really free a resource inside of the IAsyncResult implementation.&amp;nbsp; In fact if you implement IDisposable, who will see it (generally not possible since C# and VB don't support covariant return types).&amp;nbsp; Instead you should free it as part of your EndInvoke implementation.&lt;/p&gt;
&lt;p&gt;Now BeginInvoke and EndInvoke.&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(43,145,175)"&gt;IAsyncResult&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ISynchronizeInvoke&lt;/span&gt;.BeginInvoke(&lt;span style="color: rgb(43,145,175)"&gt;Delegate&lt;/span&gt; method, &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt;[] args)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;AsyncResult&lt;/span&gt;(method, args);
        }

        &lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ISynchronizeInvoke&lt;/span&gt;.EndInvoke(&lt;span style="color: rgb(43,145,175)"&gt;IAsyncResult&lt;/span&gt; result)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; r = (&lt;span style="color: rgb(43,145,175)"&gt;AsyncResult&lt;/span&gt;)result;
            &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;            {
                r.AsyncWaitHandle.WaitOne();
            }
            &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;            {
                r.AsyncWaitHandle.Close();
            }

            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (r.m_exception != &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"Error during BeginInvoke"&lt;/span&gt;, r.m_exception);
            }
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; r.m_return;
        }&lt;/pre&gt;
&lt;p&gt;Unfortunately EndInvoke has to take care of two cases.&amp;nbsp; The first is the delegate completed successfully and produced a value which can now be returned as a part of the interface contract.&amp;nbsp; The other case is when the delegate throws and exception and it's a bit more tricky.&amp;nbsp; The exception cannot be simply re-thrown because you will loose all of the original call stack and generally speaking most of the data which would help track down the problem.&amp;nbsp; The better option is to throw a new exception and make this exception the inner exception.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;This sample could be improved in a few ways (delay create the WaitHandle, rethrow with something other than System.Exception).&amp;nbsp; But it's a compliant version that gets the job done.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7022839" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Testing/default.aspx">Testing</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Threading/default.aspx">Threading</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/ISynchronizeInvoke/default.aspx">ISynchronizeInvoke</category></item></channel></rss>