如何在IRequestChannel中使用Task.Factory.FromAsync?

时间:2015-09-23 14:19:59

标签: wcf async-await

我创建了一个IRequestChannel的ChannelFactory:

ChannelFactory<IRequestChannel> channelFactory = new ChannelFactory<IRequestChannel>(endpoint);
IRequestChannel outputChannel = channelFactory.CreateChannel(address);
outputChannel.Open();
responseMessage = outputChannel.Request(message);

我想应用基于任务的Asyncronous模式。 由于IRequestChannel没有异步方法,我需要一种方法来使用outputChannel.BeginRequest和outputChannel.EndRequest。

我相信这可以通过以下方式完成:

Task.Factory.FromAsync()

如何将BeginRequest / EndRequest与FromAsync结合使用?

1 个答案:

答案 0 :(得分:1)

经过一番搜索,我得到了以下解决方案:

 using System;
 using System.ServiceModel.Channels;
 using System.Threading.Tasks;

 public static class RequestChannelExtensions
 {
     public static async Task<Message> RequestAsync(this IRequestChannel      requestChannel, Message message)
     {
         // this will be our entry that will know when our async operation is completed
         var taskCompletionSource = new TaskCompletionSource<Message>();

         try
         {
             requestChannel.BeginRequest(message, asyncResult =>
             {
                 try
                 {
                     var resultMessage = requestChannel.EndRequest(asyncResult);
                     taskCompletionSource.TrySetResult(resultMessage);
                 }
                 catch (OperationCanceledException)
                 {
                     // if the inner operation was canceled, this task is cancelled too
                     taskCompletionSource.TrySetCanceled();
                 }
                 catch (Exception ex)
                 {
                     // general exception has been set
                     taskCompletionSource.TrySetException(ex);
                 }
             }, null);
         }
         catch
         {
             taskCompletionSource.TrySetResult(default(Message));
             //propagate exception to the outside
             throw;
         }

         return await taskCompletionSource.Task;
     }
 }