Ejemplo n.º 1
0
        /// <summary>
        /// EAP (Event-based Asynchronous Pattern : 이벤트기반 비동기 패턴) 작업에서, 작업 완료시의 후속조치를 정의합니다.
        /// </summary>
        /// <typeparam name="T">비동기 작업 결과물의 수형</typeparam>
        /// <param name="tcs">비동기 작업을 표현하는 delegate</param>
        /// <param name="e">비동기 작업완료 이벤트 인자</param>
        /// <param name="getResult">작업완료 시에 결과 반환 메소드</param>
        /// <param name="unregisterHandler">작업완료 이벤트 핸들러를 등록취소하는 Action</param>
        public static void HandleCompletion <T>(TaskCompletionSource <T> tcs,
                                                AsyncCompletedEventArgs e,
                                                Func <T> getResult,
                                                Action unregisterHandler)
        {
            tcs.ShouldNotBeNull("tcs");
            e.ShouldNotBeNull("e");

            if (e.UserState != tcs)
            {
                return;
            }

            getResult.ShouldNotBeNull("getResult");

            if (e.Cancelled)
            {
                tcs.TrySetCanceled();
            }

            else if (e.Error != null)
            {
                tcs.TrySetException(e.Error);
            }

            else
            {
                tcs.TrySetResult(getResult());
            }

            if (unregisterHandler != null)
            {
                unregisterHandler();
            }
        }
        /// <summary>
        /// <paramref name="task"/>의 상태에 따라 <paramref name="resultSetter"/>의 작업 결과를 설정을 시도합니다.
        /// </summary>
        /// <typeparam name="TResult">작업 결과의 수형</typeparam>
        /// <param name="resultSetter">작업 결과를 설정할 인스턴스</param>
        /// <param name="task">작업</param>
        /// <returns>설정 성공 여부</returns>
        public static bool TrySetFromTask <TResult>(this TaskCompletionSource <TResult> resultSetter, Task task)
        {
            resultSetter.ShouldNotBeNull("resultSetter");
            task.ShouldNotBeNull("task");

            if (IsDebugEnabled)
            {
                log.Debug("resultSetter의 작업 결과를 task의 상태에 따라 설정을 시도합니다... task.Status=[{0}]", task.Status);
            }

            switch (task.Status)
            {
            case TaskStatus.RanToCompletion:
                return(resultSetter.TrySetResult(task is Task <TResult>?((Task <TResult>)task).Result: default(TResult)));

            case TaskStatus.Faulted:
                return(resultSetter.TrySetException(task.Exception.InnerExceptions));

            case TaskStatus.Canceled:
                return(resultSetter.TrySetCanceled());

            default:
                throw new InvalidOperationException("작업이 완료되지 않았습니다!!!");
            }
        }
Ejemplo n.º 3
0
        internal static IEnumerable <Task> TrackedSequenceInternal(IEnumerable <Func <Task> > functions,
                                                                   TaskCompletionSource <IList <Task> > tcs)
        {
            tcs.ShouldNotBeNull("tcs");

            if (IsDebugEnabled)
            {
                log.Debug("함수 시퀀스를 반복적으로 호출하여, 결과로 반환되는 Task를 열거합니다.");
            }

            var tasks = new List <Task>();

            foreach (var func in functions)
            {
                Task nextTask = null;
                try {
                    nextTask = func();
                }
                catch (Exception ex) {
                    if (log.IsWarnEnabled)
                    {
                        log.WarnException("함수 호출에서 예외가 발생했습니다.", ex);
                    }

                    tcs.TrySetException(ex);
                }

                if (nextTask == null)
                {
                    yield break;
                }

                yield return(nextTask);

                if (nextTask.IsFaulted)
                {
                    break;
                }
            }

            tcs.TrySetResult(tasks);
        }