Esempio n. 1
0
        /// <summary>
        /// 지정된 wait handle이 signal이 켜졌을 때 완료하는 Task를 빌드합니다.
        /// 비동기 방식의 작업 중 WaitHandle만 있을 경우, Task로 Wrapping하여, 후속 작업 등을 정의할 수 있도록 할 수 있습니다.
        /// </summary>
        /// <param name="factory">target factory</param>
        /// <param name="waitHandle">작업 완료를 결정하는 wait handle</param>
        /// <returns><paramref name="waitHandle"/>에 신호가 들어오면, 완료되는 작업</returns>
        public static Task FromAsync(this TaskFactory factory, WaitHandle waitHandle)
        {
            factory.ShouldNotBeNull("factory");
            waitHandle.ShouldNotBeNull("waitHandle");

            if (IsDebugEnabled)
            {
                log.Debug("waitHandle의 Signal을 대기하고, Signal이 켜지면, 완료되는 Task를 빌드합니다.");
            }

            var tcs = new TaskCompletionSource <object>();

            // 1. waitHandle에 signal이 켜지면, task를 완료시키는 callback 함수를 등록합니다.
            //
            var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle,
                                                             delegate { tcs.TrySetResult(null); },
                                                             null,
                                                             Timeout.Infinite,
                                                             true);

            var task = tcs.Task;

            // 2. task 완료시에 등록된 WaitHandle을 제거하기 위한 후속 작업을 정의합니다.
            //
            task.ContinueWith(_ => rwh.Unregister(waitHandle), TaskContinuationOptions.ExecuteSynchronously);

            return(task);
        }