实现异步WCF服务

sti*_*k81 6 .net service wcf asynchronous

我有一个WPF应用程序,我正在使用WCF分离到客户端和服务器端.我不喜欢我最初用直接解决方案得到的混乱,所以现在我正在根据MCFel Castro,WCF Extreme的截屏视频中的建议进行重组.如果您不熟悉视频,他基本上手动设置整个通信 - 不使用服务引用.这包括:

  • 与所有服务和数据合同的通用合同 - 由客户端和服务器引用
  • 托管服务的控制台应用程序
  • 客户端上的代理类映射服务,并将调用传递给它(使用ClientBase或ClientFactory)

我已经完成了他所有的步骤,我真的很喜欢这里的发展方向.但是,他没有解决异步服务调用,这就是我想要使用的.

添加服务引用时,我可以选中"生成异步操作"复选框,然后获取MyServiceCompleted和MyServiceAsync.但是,我想这是在添加服务引用时生成的东西,而不是这个构建的类中的一些魔法?

那么,我能以某种方式从ClientBase或ClientFactory获取异步操作吗?或者我是否必须将实际的服务器端服务定义为异步?如果是这样 - 有人可以给我一些关于如何开始使用简单异步服务的提示或示例吗?我一直在MSDN上阅读这个主题,但它让我感到很困惑,因为我已经没有得到这个了...

Gor*_*ran 5

在服务器端实现异步操作非常简单.确保方法名称匹配,并以Begin和End为前缀.GetImageAsyncResult是一个自定义的IAsyncResult实现(Web上有很多示例).

    public class MapProvider : IMapProvider //implementation - belongs to server
    {
         public IAsyncResult BeginGetImage(int level, int x, int y, string[] layers, AsyncCallback callback, object state)
         {
              GetImageAsyncResult asyncResult = new GetImageAsyncResult(level, x, y, layers, callback, state);
              ThreadPool.QueueUserWorkItem(Callback, asyncResult);
              return asyncResult;
         }

         private void Callback(object state)
         {

              GetImageAsyncResult asyncResult = state as GetImageAsyncResult;
              asyncResult.Image = TileProvider.GetImage(asyncResult.Level, asyncResult.X, asyncResult.Y, asyncResult.Layers);
              asyncResult.Complete();
         }

         public System.Drawing.Bitmap EndGetImage(IAsyncResult result)
         {
              using (GetImageAsyncResult asyncResult = result as GetImageAsyncResult)
              {
                   asyncResult.AsyncWait.WaitOne();
                   return asyncResult.Image;
              }
         }
    }

    public class MapProviderProxy : ClientBase<IMapProvider>, IMapProvider, IDisposable
    {
         public IAsyncResult BeginGetImage(int level, int x, int y, string[] layers, AsyncCallback callback, object state)
         {
              return Channel.BeginGetImage(level, x, y, layers, callback, state);
         }

         public System.Drawing.Bitmap EndGetImage(IAsyncResult result)
         {
              return Channel.EndGetImage(result);
         }

         public void Dispose()
         {
              if (State == CommunicationState.Faulted)
              {
                   Abort();
              }
              else
              {
                   try
                   {
                        Close();
                   }
                   catch
                   {
                        Abort();
                   }
              }
         }
    }
Run Code Online (Sandbox Code Playgroud)