title: Using a custom SynchronizationContext to serialize execution when using async/await
body: <p>My team is developing a multi-threaded application using async/await in C# 5.0. In the process of implementing thread synchronization, after several iterations, we came up with a (possibly novel?) new SynchronizationContext implementation with an internal lock that:</p>
  
  <ol>
  <li>When calling Post: 
  <ul>
  <li>if a lock can be taken, the delegate is executed immediately</li>
  <li>if a lock cannot be taken, the delegate is queued</li>
  </ul></li>
  <li>When calling Send:
  <ul>
  <li>if a lock can be taken the delegate is executed</li>
  <li>if a lock cannot be taken, the thread is blocked</li>
  </ul></li>
  </ol>
  
  <p>In all cases, before executing the delegate, the context sets itself as the current context and restores the original context when the delegate returns.</p>
  
  <p>It’s an unusual pattern and since we’re clearly not the first people writing such an application I’m wondering:</p>
  
  <ol>
  <li><strong>Is the pattern really safe?</strong></li>
  <li><strong>Are there better ways of achieving thread synchronization?</strong></li>
  </ol>
  
  <p>Here’s the source for SerializingSynchronizationContext and a demo on <a href="https://github.com/revane/SerializingSynchronizationContext">GitHub</a>.</p>
  
  <p>Here’s how it’s used:</p>
  
  <ul>
  <li>Each class wanting protection creates its own instance of the context like a mutex.</li>
  <li><p>The context is awaitable so that statements like the following are possible.</p>
  
  <p><code>await myContext;</code></p>
  
  <p>This simply causes the rest of the method to be run under protection of the context.</p></li>
  <li>All methods and properties of the class use this pattern to protect data. Between awaits, only one thread can run on the context at a time and so state will remain consistent. When an await is reached, the next scheduled thread is allowed to run on the context.</li>
  <li>The custom SynchronizationContext can be used in combination with AsyncLock if needed to maintain atomicity even with awaited expressions.</li>
  <li>Synchronous methods of a class can use custom context for protection as well.</li>
  </ul>