Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>We need to thank Stephen Toub here, as he has some very useful async locking constructs demonstrated in a blog series, including an <a href="http://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266988.aspx">async lock</a> block.</p> <p>Here is the code from that article (including some code from the previous article in the series):</p> <pre><code>public class AsyncLock { private readonly AsyncSemaphore m_semaphore; private readonly Task&lt;Releaser&gt; m_releaser; public AsyncLock() { m_semaphore = new AsyncSemaphore(1); m_releaser = Task.FromResult(new Releaser(this)); } public Task&lt;Releaser&gt; LockAsync() { var wait = m_semaphore.WaitAsync(); return wait.IsCompleted ? m_releaser : wait.ContinueWith((_, state) =&gt; new Releaser((AsyncLock)state), this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } public struct Releaser : IDisposable { private readonly AsyncLock m_toRelease; internal Releaser(AsyncLock toRelease) { m_toRelease = toRelease; } public void Dispose() { if (m_toRelease != null) m_toRelease.m_semaphore.Release(); } } } public class AsyncSemaphore { private readonly static Task s_completed = Task.FromResult(true); private readonly Queue&lt;TaskCompletionSource&lt;bool&gt;&gt; m_waiters = new Queue&lt;TaskCompletionSource&lt;bool&gt;&gt;(); private int m_currentCount; public AsyncSemaphore(int initialCount) { if (initialCount &lt; 0) throw new ArgumentOutOfRangeException("initialCount"); m_currentCount = initialCount; } public Task WaitAsync() { lock (m_waiters) { if (m_currentCount &gt; 0) { --m_currentCount; return s_completed; } else { var waiter = new TaskCompletionSource&lt;bool&gt;(); m_waiters.Enqueue(waiter); return waiter.Task; } } } public void Release() { TaskCompletionSource&lt;bool&gt; toRelease = null; lock (m_waiters) { if (m_waiters.Count &gt; 0) toRelease = m_waiters.Dequeue(); else ++m_currentCount; } if (toRelease != null) toRelease.SetResult(true); } } </code></pre> <p>Now applying it to your case:</p> <pre><code>private readonly AsyncLock m_lock = new AsyncLock(); private async void OnMessageReceived(object sender, EventArgs e) { using(var releaser = await m_lock.LockAsync()) { await Task.Run(() =&gt; this.model.Apply(e)); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload