2011-06-03 87 views

回答

2

就客户而言,服务的同步或异步版本是相同的(请参阅下面的示例)。因此,同步/异步决策不会影响互操作性。

public class StackOverflow_6231864_751090 
{ 
    [ServiceContract(Name = "ITest")] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string text); 
     [OperationContract] 
     int Add(int x, int y); 
    } 
    [ServiceContract(Name = "ITest")] 
    public interface ITestAsync 
    { 
     [OperationContract(AsyncPattern = true)] 
     IAsyncResult BeginEcho(string text, AsyncCallback callback, object state); 
     string EndEcho(IAsyncResult ar); 
     [OperationContract(AsyncPattern = true)] 
     IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object state); 
     int EndAdd(IAsyncResult ar); 
    } 
    public class Service : ITest 
    { 
     public string Echo(string text) { return text; } 
     public int Add(int x, int y) { return x + y; } 
    } 
    public class ServiceAsync : ITestAsync 
    { 
     string Echo(string text) { return text; } 
     int Add(int x, int y) { return x + y; } 
     public IAsyncResult BeginEcho(string text, AsyncCallback callback, object state) 
     { 
      Func<string, string> func = Echo; 
      return func.BeginInvoke(text, callback, state); 
     } 

     public string EndEcho(IAsyncResult ar) 
     { 
      Func<string, string> func = (Func<string, string>)((System.Runtime.Remoting.Messaging.AsyncResult)ar).AsyncDelegate; 
      return func.EndInvoke(ar); 
     } 

     public IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object state) 
     { 
      Func<int, int, int> func = Add; 
      return func.BeginInvoke(x, y, callback, state); 
     } 

     public int EndAdd(IAsyncResult ar) 
     { 
      Func<int, int, int> func = (Func<int, int, int>)((System.Runtime.Remoting.Messaging.AsyncResult)ar).AsyncDelegate; 
      return func.EndInvoke(ar); 
     } 
    } 
    public static void Test() 
    { 
     foreach (bool useAsync in new bool[] { false, true }) 
     { 
      Type contractType = useAsync ? typeof(ITestAsync) : typeof(ITest); 
      Type serviceType = useAsync ? typeof(ServiceAsync) : typeof(Service); 
      Console.WriteLine("Using {0} service implementation", useAsync ? "Asynchronous" : "Synchronous"); 
      string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
      ServiceHost host = new ServiceHost(serviceType, new Uri(baseAddress)); 
      host.AddServiceEndpoint(contractType, new BasicHttpBinding(), ""); 
      host.Open(); 
      Console.WriteLine("Host opened"); 

      Console.WriteLine("Using the same client for both services..."); 
      ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)); 
      ITest proxy = factory.CreateChannel(); 
      Console.WriteLine(proxy.Echo("Hello")); 
      Console.WriteLine(proxy.Add(3, 4)); 

      ((IClientChannel)proxy).Close(); 
      factory.Close(); 

      host.Close(); 

      Console.WriteLine("Done"); 
      Console.WriteLine(); 
     } 
    } 
} 
+0

你在问题和你的用户ID之后命名了这个类? :) +1,简洁而有指导性的代码。我喜欢两个版本都使用“ITest”的代理。 – shambulator 2011-06-03 20:59:33

+0

我刚刚得到了问题中的“链接”值,我不知道用户标识是在它:) – carlosfigueira 2011-06-03 21:06:21

1

如果通过“使服务异步”,你的意思是使用AsyncPattern,那么我的理解是,这对客户端根本没有影响,只有WCF运行时如何调用服务器上的操作。客户端(即一个WCF客户端)和以往一样,自行选择是否使用异步调用。

From this MSDN page

要定义执行异步不管它是如何被调用的客户端应用程序的合同操作X ...

和:

在在这种情况下,异步操作以与同步操作相同的形式显示在元数据中:它作为单个操作公开,并带有请求消息和ac相关的响应消息。客户端编程模型则有一个选择。他们可以将此模式表示为同步操作或异步模式,只要服务被调用时发生请求 - 响应消息交换即可。

1

你的服务不需要做任何“特殊的”......他们仍然表现得一样。另一方面,客户必须使用异步模式来使用服务。最简单的方法是使用“添加服务引用...”。只需选中一个小盒子,上面写着“生成异步操作”,瞧,你可以让你的服务的异步调用...

这里有一个很好的资源:How to: Call WCF Service Operations Asynchronously

尽管负面评论,在最后的例子很好。只需订阅 <服务名称>完成事件,然后进行异步调用。调用完成后,您的UI线程将被释放,并且只要呼叫完成,事件就会发生!小心你的新发现的力量!

public class Foo 
{ 
    private BarServiceClient client; 

    public Foo() 
    { 
     client = new BarServiceClient(); 
     client.DoWorkCompleted += Client_DoWorkCompleted; 
    } 

    private void Client_DoWorkCompleted(object sender, DoWorkCompletedEventArgs e) 
    { 
     //e.Result contains your result. 
    } 

    public void DoBar() 
    { 
     client.DoWorkAsync(); //Called asynchronously, UI thread is free! :) 
    } 
}