{"id":1263,"date":"2010-10-31T00:10:14","date_gmt":"2010-10-30T23:10:14","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=1263"},"modified":"2021-07-03T13:27:11","modified_gmt":"2021-07-03T12:27:11","slug":"c-5-0-async-feature-be-aware-of-the-synchronization-context","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2010\/10\/c-5-0-async-feature-be-aware-of-the-synchronization-context\/","title":{"rendered":"C# 5.0 Async-Feature: Be Aware Of The Synchronization-Context"},"content":{"rendered":"<p><span style=\"color: #ff0000; font-size: medium;\">Disclaimer: <\/span><span style=\"font-size: medium;\">This post is based on the C# 5.0 CTP. Everything described here is subject to future changes. <\/span><\/p>\n<p>The next version of C# and VB.NET will have support for asynchronous programming. In this post I don\u2019t want to explain how it works and what you can do with it. For an introduction watch <a href=\"http:\/\/player.microsoftpdc.com\/Session\/1b127a7d-300e-4385-af8e-ac747fee677a\">Anders Hejlsberg\u2019s presentation<\/a> from PDC 2010. There are more resources on <a href=\"http:\/\/msdn.microsoft.com\/en-gb\/vstudio\/async.aspx\">the CTP-site<\/a> like Channel 9 videos, white-papers, examples and the CTP-binaries so that you can try the new features yourself.<\/p>\n<p>I just want to focus on a very small detail of the async-feature. I assume that you\u2019ve already informed yourself and know the basic bits. Let\u2019s get started. As we know we can write code like this with the new async feature:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=asyncExample.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">var client = new WebClient();\nvar webContent = await client.DownloadStringTaskAsync(&quot;http:\/\/www.gamlor.info\/wordpress\/&quot;);\nProcessFurther(webContent);<\/code><\/pre><\/noscript><\/p>\n<p>Now the compiler turns this code it turned inside out. The first part before the await operator is executed normally. Then rest of the method is packed into a continuation object which captures the state and logic to run asynchronous. Then the download is started, the continuation is passed to download task and the method returns immediately. As soon as the download is finished, the rest of the code is continued. As <a href=\"http:\/\/player.microsoftpdc.com\/Session\/1b127a7d-300e-4385-af8e-ac747fee677a\">Anders Hejlsberg <\/a> showed in his demo, all our code is actually executed on the same thread! The async feature doesn&#8217;t do any multi threading by itself. For example when you write a simple desktop application and use the async stuff your code is executed on the GUI-thread. You don&#8217;t need to do any locking. Let\u2019s run this example-code in a WPF-Application and watch the output:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=ThreadInfo.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">Console.Out.WriteLine(&quot;We are on Thread No {0}&quot;,Thread.CurrentThread.ManagedThreadId);\nvar client = new WebClient();\nvar webContentHomePage = await client.DownloadStringTaskAsync(&quot;http:\/\/www.gamlor.info\/wordpress\/&quot;);\nConsole.Out.WriteLine(&quot;We are on Thread No {0}&quot;,Thread.CurrentThread.ManagedThreadId);\nConsole.Out.WriteLine(&quot;Page is {0} characters long&quot;,webContentHomePage.Length);<\/code><\/pre><\/noscript><\/p>\n<p>The output is:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=outputOnWpf.txt\"><\/script><noscript><pre><code class=\"language-text text\">We are on Thread No 10\nDownloaded 67770 characters, continue with the work\nWe are on Thread No 10<\/code><\/pre><\/noscript><\/p>\n<p>So our code is running on the same thread. This makes programming an GUI application so much easier. The async operations just work! Cool, right?<\/p>\n<h2>Oh rly? The Same Thread?<\/h2>\n<p>Ok, in reality it&#8217;s not that simple. We know that the async-feature is based on .NET 4.0 Tasks. (ok, actually on the right method-signatures, but that\u2019s a detail). The compiler builds the continuation-state machines for us, packs those into tasks and finally composes those tasks. But how the hell does the system ensure that the code is executed on the right thread? For example on the GUI-thread? Well lets run our example code again. This time in a simple console application. The output is:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=outputConsole.txt\"><\/script><noscript><pre><code class=\"language-text text\">We are on Thread No 10\nDownloaded 67770 characters, continue with the work\nWe are on Thread No 16<\/code><\/pre><\/noscript><\/p>\n<p>Oh, oh,&nbsp; the code after the \u2018await\u2019 is executed on a different thread! So something seem to be wrong.<\/p>\n<h2>The Synchronization Context<\/h2>\n<p>So why do all the WPF \/ Silverlight examples work? Think about the process again: The whole point of the await operator is that you can instrument your code to run asynchronous while preserving the flow of your logic. However at some lower level something needs to actually run asynchronously. After it completes it calls back into our code. But it cannot \u2018magically\u2019 run code on another thread. That\u2019s where the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.threading.synchronizationcontext.aspx\">synchronization context<\/a> comes in. The synchronization context is an abstraction which represents the \u2018right\u2019 callback context. It has been around since .NET 2.0. For example in a GUI application the synchronization context is the message-pump. In a thread pool the synchronization context could be the thread pool itself. It really depends on the context of your application.<\/p>\n<p>In a WPF, Winforms, Silverlight app the synchronization context is set up for the main thread and represents the message pump. When in our example the asynchronous operation completes, it passes the continuation to the synchronization context, which adds it to the message pump. At some point in time the continuation is picked up and executed on the GUI-thread.<\/p>\n<h2>Your Own Synchronization Context<\/h2>\n<p>You can provide your own synchronization context. Of course for most application this isn\u2019t necessary. And it&#8217;s certainly not easy to get right. Anyway, how do we get the console-application to run the async stuff on the same thread? We write a simple synchronization context which is just enough for the example. It is a message-pump like in a GUI application.<\/p>\n<p>First we implement the synchronization context. To make this example simple this class implements the message pump and the synchronization context:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=MyPrimitiveSynchronisationContext.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">class MyPrimitiveSynchronisationContext : SynchronizationContext\n{\n    private readonly Queue&lt;Action&gt; messagesToProcess = new Queue&lt;Action&gt;();\n    private readonly object syncHandle = new object();\n    private bool isRunning = true;\n\n    public override void Send(SendOrPostCallback codeToRun, object state)\n    {\n        throw new NotImplementedException();\n    }\n\n    public override void Post(SendOrPostCallback codeToRun, object state)\n    {\n        lock (syncHandle)\n        {\n            messagesToProcess.Enqueue(() =&gt; codeToRun(state));\n            SignalContinue();\n        }\n    }\n\n    public void RunMessagePump()\n    {\n        while(CanContinue())\n        {\n            Action nextToRun = GrabItem();\n            nextToRun();\n        }            \n    }\n\n    private Action GrabItem()\n    {\n        lock (syncHandle)\n        {\n            while (CanContinue() &amp;&amp; messagesToProcess.Count == 0)\n            {\n                Monitor.Wait(syncHandle);\n            }\n            return messagesToProcess.Dequeue();\n        }\n    }\n\n    private bool CanContinue()\n    {\n        lock (syncHandle)\n        {\n            return isRunning;\n        }\n    }\n\n    public void Cancel()\n    {\n        lock (syncHandle)\n        {\n            isRunning = false;\n            SignalContinue();\n        }\n    }\n\n    private void SignalContinue()\n    {\n        Monitor.Pulse(syncHandle);\n    }\n}<\/code><\/pre><\/noscript><\/p>\n<p>Then we kick of the main application. We set up the synchronization context, add the regular code as initial the message to the message-pump and the start running it:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=Programm.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">class Program\n{\n    static void Main(string[] args)\n    {\n        \/\/ Setup our synchronisation context\n        MyPrimitiveSynchronisationContext ctx = new MyPrimitiveSynchronisationContext();\n        MyPrimitiveSynchronisationContext.SetSynchronizationContext(ctx);\n\n        \/\/ The first thing to process is our main application\n        ctx.Post(obj=&gt;\n            MainProgramm(), null);\n\n        \/\/ Then we kick of the message pump\n        ctx.RunMessagePump();\n    }\n\n    static async void MainProgramm(){\n        Console.Out.WriteLine(&quot;We are on Thread No {0}&quot;, Thread.CurrentThread.ManagedThreadId);\n        var client = new WebClient();\n        var webContentHomePage = await client.DownloadStringTaskAsync(&quot;http:\/\/www.gamlor.info\/wordpress\/&quot;);\n        Console.Out.WriteLine(&quot;Downloaded {0} characters, continue with the work&quot;, webContentHomePage.Length);\n        Console.Out.WriteLine(&quot;We are on Thread No {0} &quot;, Thread.CurrentThread.ManagedThreadId);\n    }\n}<\/code><\/pre><\/noscript><\/p>\n<p>And now our console application works like the GUI application:<br \/>\n<script src=\"https:\/\/gist.github.com\/655758.js?file=consoleAfterSyncContext.txt\"><\/script><noscript><pre><code class=\"language-text text\">We are on Thread No 10\nDownloaded 67770 characters, continue with the work\nWe are on Thread No 10<\/code><\/pre><\/noscript><\/p>\n<h2>Conclusion<\/h2>\n<p>The async feature of C# and VB.NET is awesome. It really makes asynchronous programming so much easier. However don\u2019t be fooled and believe that everything just works. I recommend you to try out the CTP and try to understand how it works.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer: This post is based on the C# 5.0 CTP. Everything described here is subject to future changes. The next version of C# and VB.NET will have support for asynchronous&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[126],"tags":[21,200,24,199],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1263"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=1263"}],"version-history":[{"count":26,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1263\/revisions"}],"predecessor-version":[{"id":3873,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1263\/revisions\/3873"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=1263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=1263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=1263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}