Exemple #1
0
        /// <summary>
        /// Internet Control Message Protocol (ICMP) echo message 를 비동기적으로 보냅니다.
        /// </summary>
        private static Task <PingReply> SendTaskCore(Ping ping, object userToken, Action <TaskCompletionSource <PingReply> > sendAsync)
        {
            ping.ShouldNotBeNull("ping");
            sendAsync.ShouldNotBeNull("sendAsync");

            if (IsDebugEnabled)
            {
                log.Debug("Ping 작업을 비동기적으로 수행하는 Task를 생성합니다...");
            }

            var tcs = new TaskCompletionSource <PingReply>(userToken);
            PingCompletedEventHandler handler = null;

            handler             = (sender, e) => EventAsyncPattern.HandleCompletion(tcs, e, () => e.Reply, () => ping.PingCompleted -= handler);
            ping.PingCompleted += handler;

            try {
                sendAsync(tcs);
            }
            catch (Exception ex) {
                ping.PingCompleted -= handler;
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
        private static Task <bool> SendTaskInternal(SmtpClient client, CancellationToken token, object userToken,
                                                    Action <TaskCompletionSource <bool> > sendAsyncAction)
        {
            client.ShouldNotBeNull("client");
            sendAsyncAction.ShouldNotBeNull("sendAsyncAction");

            if (IsDebugEnabled)
            {
                log.Debug("SmtpClient를 이용하여 비동기방식으로 메일을 발송합니다... SmtpHost=[{0}]", client.Host);
            }

            var tcs = new TaskCompletionSource <bool>(userToken);

            token.Register(client.SendAsyncCancel);

            SendCompletedEventHandler handler = null;

            handler = (s, e) => EventAsyncPattern.HandleCompletion(tcs,
                                                                   e,
                                                                   () => (e.Cancelled == false && e.Error != null),
                                                                   () => client.SendCompleted -= handler);
            client.SendCompleted += handler;

            try {
                sendAsyncAction(tcs);
            }
            catch (Exception ex) {
                client.SendCompleted -= handler;
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
        /// <summary>
        /// <paramref name="address"/>에 <paramref name="data"/> 문자열을 전송합니다. (HTTP나 FTP나 같습니다)
        /// </summary>
        /// <param name="webClient"><see cref="WebClient"/> 인스턴스</param>
        /// <param name="address">전송할 주소</param>
        /// <param name="method">전송 방법 (HTTP는 POST, FTP는 STOR)</param>
        /// <param name="data">전송할 문자열</param>
        /// <returns></returns>
        public static Task <string> UploadStringTask(this WebClient webClient, Uri address, string method, string data)
        {
            webClient.ShouldNotBeNull("webClient");
            address.ShouldNotBeNull("address");
            // data.ShouldNotBeEmpty("data");

            if (IsDebugEnabled)
            {
                log.Debug("지정된 주소에 문자열을 비동기 Upload합니다... address=[{0}], method=[{1}], data=[{2}]",
                          address.AbsoluteUri, method, data.EllipsisChar(255));
            }

            var tcs = new TaskCompletionSource <string>(address);

            UploadStringCompletedEventHandler handler = null;

            handler =
                (s, e) => EventAsyncPattern.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadStringCompleted -= handler);
            webClient.UploadStringCompleted += handler;

            try {
                webClient.UploadStringAsync(address, method, data, tcs);
            }
            catch (Exception ex) {
                if (log.IsWarnEnabled)
                {
                    log.Warn("WebClient를 이용하여 문자열을 비동기 Upload 하는데 실패했습니다. address=[{0}]", address.AbsoluteUri);
                    log.Warn(ex);
                }

                webClient.UploadStringCompleted -= handler;
                tcs.TrySetException(ex);
            }
            return(tcs.Task);
        }
        /// <summary>
        /// <paramref name="address"/>에 <paramref name="data"/>를 비동기적으로 전송합니다.
        /// </summary>
        /// <param name="webClient"></param>
        /// <param name="address">데이타를 전송할 주소</param>
        /// <param name="method">데이타 전송 방법 (HTTP는 POST, FTP는 STOR)</param>
        /// <param name="data">전송할 데이타</param>
        /// <returns></returns>
        public static Task <byte[]> UploadDataTask(this WebClient webClient, Uri address, string method, byte[] data)
        {
            webClient.ShouldNotBeNull("webClient");
            address.ShouldNotBeNull("address");
            data.ShouldNotBeNull("data");

            if (IsDebugEnabled)
            {
                log.Debug("지정된 주소에 데이타를 비동기 방식으로 전송합니다... address=[{0}], method=[{1}]", address.AbsoluteUri, method);
            }

            var tcs = new TaskCompletionSource <byte[]>(address);

            UploadDataCompletedEventHandler handler = null;

            handler =
                (s, e) => EventAsyncPattern.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadDataCompleted -= handler);
            webClient.UploadDataCompleted += handler;

            try {
                webClient.UploadDataAsync(address, method ?? "POST", data, tcs);
            }
            catch (Exception ex) {
                if (log.IsWarnEnabled)
                {
                    log.Warn("WebClient를 이용하여 데이타를 비동기 전송에 실패했습니다. address=[{0}]" + address.AbsoluteUri);
                    log.Warn(ex);
                }

                webClient.UploadDataCompleted -= handler;
                tcs.TrySetException(ex);
            }
            return(tcs.Task);
        }
        /// <summary>
        /// <paramref name="address"/>의 리소스를 비동기적으로 다운받아 byte array로 반환하는 Task{byte[]}를 빌드합니다.
        /// </summary>
        /// <param name="webClient"><see cref="WebClient"/> 인스턴스</param>
        /// <param name="token">작업 취소를 위한 Token</param>
        /// <param name="address">리소스 위치</param>
        /// <returns></returns>
        public static Task <byte[]> DownloadDataTask(this WebClient webClient, CancellationToken token, Uri address)
        {
            webClient.ShouldNotBeNull("webClient");
            token.ShouldNotBeNull("token");
            address.ShouldNotBeNull("address");

            if (IsDebugEnabled)
            {
                log.Debug("WebClient를 이용하여 지정된 주소로부터 리소스를 비동기 방식으로 다운받습니다... address=[{0}]", address.AbsoluteUri);
            }

            var tcs = new TaskCompletionSource <byte[]>(address);

            token.Register(webClient.CancelAsync);

            // 비동기 완료 시의 처리를 정의합니다.
            DownloadDataCompletedEventHandler handler = null;

            handler =
                (sender, args) =>
                EventAsyncPattern.HandleCompletion(tcs, args, () => args.Result, () => webClient.DownloadDataCompleted -= handler);
            webClient.DownloadDataCompleted += handler;

            try {
                webClient.DownloadDataAsync(address, tcs);
            }
            catch (Exception ex) {
                if (log.IsWarnEnabled)
                {
                    log.Warn("WebClient를 이용하여 리소스 Data를 비동기적으로 다운받는데 실패했습니다. address=[{0}]", address.AbsoluteUri);
                    log.Warn(ex);
                }

                webClient.DownloadDataCompleted -= handler;
                tcs.TrySetException(ex);
            }

            var result = tcs.Task;

            if (result.IsCompleted)
            {
                result = result.ContinueWith(antecedent => DecompressByContentEncoding(webClient, antecedent.Result),
                                             TaskContinuationOptions.ExecuteSynchronously);
            }
            return(result);
        }
        /// <summary>
        /// <paramref name="address"/>에 비동기적으로 data를 전송하기 위한 쓰기용 Stream을 반환합니다.
        /// </summary>
        /// <param name="webClient">WebClient 인스턴스</param>
        /// <param name="token">작업 취소를 위한 Token</param>
        /// <param name="address">리소스의 주소</param>
        /// <param name="method">전송 방법 : Http인 경우는 POST, FTP인 경우는 STOR입니다.</param>
        /// <returns></returns>
        public static Task <Stream> OpenWriteTask(this WebClient webClient, CancellationToken token, Uri address, string method)
        {
            webClient.ShouldNotBeNull("webClient");
            token.ShouldNotBeNull("token");
            address.ShouldNotBeNull("address");

            if (IsDebugEnabled)
            {
                log.Debug("지정된 주소에 데이타 쓰기용 Stream을 엽니다... address=[{0}], method=[{1}]", address.AbsoluteUri, method);
            }


            var tcs = new TaskCompletionSource <Stream>(address);

            token.Register(webClient.CancelAsync);

            OpenWriteCompletedEventHandler handler = null;

            handler =
                (s, e) => EventAsyncPattern.HandleCompletion(tcs, e, () => e.Result, () => webClient.OpenWriteCompleted -= handler);
            webClient.OpenWriteCompleted += handler;

            try {
                webClient.OpenWriteAsync(address, method, tcs);
            }
            catch (Exception ex) {
                if (log.IsWarnEnabled)
                {
                    log.Warn("WebClient를 이용하여 데이타를 전송하기 위해 쓰기용 Stream을 오픈하는데 실패했습니다. address=[{0}]", address.AbsoluteUri);
                    log.Warn(ex);
                }

                webClient.OpenWriteCompleted -= handler;
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
        /// <summary>
        /// <paramref name="address"/>에 <paramref name="filename"/>의 파일을 전송합니다. (HTTP나 FTP나 같습니다)
        /// </summary>
        /// <param name="webClient"><see cref="WebClient"/> 인스턴스</param>
        /// <param name="address">전송할 주소</param>
        /// <param name="method">전송 방법 (HTTP는 POST, FTP는 STOR)</param>
        /// <param name="filename">전송할 파일의 전체경로</param>
        /// <returns></returns>
        public static Task <byte[]> UploadFileTask(this WebClient webClient, Uri address, string method, string filename)
        {
            webClient.ShouldNotBeNull("webClient");
            address.ShouldNotBeNull("address");
            filename.ShouldNotBeWhiteSpace("filename");
            Guard.Assert <FileNotFoundException>(File.Exists(filename), "File not found. filename=[{0}]", filename);

            if (IsDebugEnabled)
            {
                log.Debug("지정된 주소에 파일을 비동기 방식으로 Upload합니다... address=[{0}], method=[{1}], filename=[{2}]", address.AbsoluteUri, method,
                          filename);
            }

            var tcs = new TaskCompletionSource <byte[]>(address);

            UploadFileCompletedEventHandler handler = null;

            handler =
                (s, e) => EventAsyncPattern.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadFileCompleted -= handler);
            webClient.UploadFileCompleted += handler;

            try {
                webClient.UploadFileAsync(address, method, filename, tcs);
            }
            catch (Exception ex) {
                if (log.IsWarnEnabled)
                {
                    log.Warn("WebClient를 이용하여 파일을 비동기 방식 Upload에 실패했습니다. address=[{0}]" + address.AbsoluteUri);
                    log.Warn(ex);
                }

                webClient.UploadFileCompleted -= handler;
                tcs.TrySetException(ex);
            }
            return(tcs.Task);
        }