Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing BeginInvoke/EndInvoke in a multithreaded fashion. How do AsyncCallback, AsyncWaitHandle and IsCompleted interact?
    text
    copied!<p>Andreas Huber's answer to <a href="https://stackoverflow.com/questions/405600/detecting-that-a-threadpool-workitem-has-completed-waiting-for-completion">this question</a> gave me an idea to implement <code>Concurrent&lt;T&gt;</code> with async delegates instead of the ThreadPool. However, I am finding it harder to understand what's going on when an <code>AsyncCallback</code> is passed to <code>BeginInvoke</code>, especially when several threads have access to <code>IAsyncResult</code>. Unfortunately, this case doesn't seem to be covered at MSDN or anywhere I could find. Moreover, all articles I could find were either written before closures and generics were available or just seem that way. There are several questions (and the answers which I hope are true, but I am ready to be disappointed):</p> <p>1) Would using a closure as an AsyncCallback make any difference?<br> (Hopefully not)<br> 2) If a thread waits on the <code>AsyncWaitHandle</code>, will it be signaled<br> a) before the callback starts or b) after it finishes?<br> (Hopefully b)<br> 3) While the callback is running, what will <code>IsCompleted</code> return? Possibilities I can see:<br> a) <code>true</code>; b) <code>false</code>; c) <code>false</code> before the callback calls EndInvoke, <code>true</code> after.<br> (Hopefully b or c)<br> 4) Will <code>DisposedObjectException</code> be thrown if some thread waits on the <code>AsyncWaitHandle</code> after <code>EndInvoke</code> is called?<br> (Hopefully not, but I expect yes).</p> <p>Provided the answers are as I hope, this seems like it should work:</p> <pre><code>public class Concurrent&lt;T&gt; { private IAsyncResult _asyncResult; private T _result; public Concurrent(Func&lt;T&gt; f) { // Assume f doesn't throw exceptions _asyncResult = f.BeginInvoke( asyncResult =&gt; { // Assume assignment of T is atomic _result = f.EndInvoke(asyncResult); }, null); } public T Result { get { if (!_asyncResult.IsCompleted) // Is there a race condition here? _asyncResult.AsyncWaitHandle.WaitOne(); return _result; // Assume reading of T is atomic } ... </code></pre> <p>If the answers to the questions 1-3 are the ones I hope for, there should be no raace condition here, as far as I can see.</p>
 

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