Async Coordination Primitives

???????? Building Async Coordination Primitives, Part 1: AsyncManualResetEvent ???????????? TAP ?? ManualResetEvent ?????????? Wait ?????? asynchronous! ?????????????????????? async/await ?????????????????????????? ???????????? WaitAsync() ?? ManualResetEvent/AutoResetEvent ?? ... (??????? SemaphoreSlim ???? ?????... Event ??? Semaphore ????????????????? 100% ?????)

????????? TaskCompletionSource<bool> ?????? wait ???????? ?? WaitAsync() ??? Set() ???????? (??????? WaitAsync ?????? timeout ?????? :s )

TaskCompletionSource<bool> src = new TaskCompletionSource<bool>();  
 Task WaitAsync() { return src.Task; }
 void Set() { src.TrySetResult(true); }

??????? Reset() ????????????????????????? ??????????????????? TaskCompletionSource ??? set ?????? ??? reset ????????? ??????? new ?????????? ??????????????? access Set() ??? WaitAsync() ??? Reset() ????????? ??????????????????? new ?????????????"?????????" 

???????????? ?? 3 threads: t1, t2, t3 ?????? t1 ?????????? WaitAsync() ?????? t2 ??? t3 ?????????? Reset() ... ??????????????????? execute ????????? t1 t2 t3 ???????? ???????????? instance ??? reset ??? t2 ???????????? replace ??? t3 ??????????????? set (???????????? t1 ???????????? ????? Set() ????????? instance ??????????????? t3)

??????? code ??????? Reset ???????? spin exchange ?????? check completion ??? Task ????????????

void Reset(){  
 TaskCompletionSource&lt;bool&gt; current;
 while((current = source).Task.IsCompleted
 && Interlocked.CompareExchange(ref source, new TaskCompletionSource<bool>(), current) != current){}
 }

??????????????? ??????????????? WaitHandle ???????? WaitOneAsync ?????? ??????????????????????????? TAP ???? 33 ?????? ThreadPool.RegisterWaitForSingleObject() ????????????????????? WaitAsync() ???????????? timeout ???????? timeout!

   Task WaitAsyncWaitHandle wait, int milliseconds = -1){
            var result = new TaskCompletionSource();
            var registration = ThreadPool.RegisterWaitForSingleObject(wait,
                                                                      (state,timedout) => result.TrySetResult(!timedout),
                                                                      null, milliseconds,
                                                                      executeOnlyOnce: true);
            result.Task.ContinueWith(_ => registration.Unregister(null));
            return result.Task;
    }

??????????? ManualResetEventSlim ?????????????????? inherit ??? WaitHandle ???? ????????????????????? spin check ???????????? kernel Wait object ??????? WaitAsync() ??????????? ManualResetEventSlim ?????????????????????? ???????? spin check ?????? :D

   Task WaitAsync(ManualResetEventSlim wait, int milliseconds){
            var counter = wait.SpinCount;
            var watch = Stopwatch.StartNew();
            while(!wait.IsSet && counter-- > 0 && watch.ElapsedMilliseconds &lt;= milliseconds){}
            if (wait.IsSet)
                return Task.FromResult(true);
            var elasped = (int) watch.ElapsedMilliseconds;
            if (elasped > milliseconds)
                return Task.FromResult(false);
            else
                return WaitAsync(wait.WaitHandle, milliseconds - elasped); // ????????? Kernel wait object
        }

???????????????????? work ??? ^^