基本上问题是,如果我使我的服务异步,这意味着它们不再具有互操作性了吗?
答案 0 :(得分: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();
}
}
}
答案 1 :(得分:1)
如果通过“使服务异步”,你的意思是使用AsyncPattern
,那么我的理解是这根本不会对客户端产生影响,只会影响WCF运行时如何调用服务器上的操作。客户端(WCF客户端)一如既往地决定是否使用异步调用。
定义一个异步执行的契约操作X,无论它在客户端应用程序中如何被调用......
和
在这种情况下,异步操作以与同步操作相同的形式在元数据中公开:它作为具有请求消息和相关响应消息的单个操作公开。然后客户端编程模型可以选择。它们可以将此模式表示为同步操作或异步操作,只要在调用服务时发生请求 - 响应消息交换。
答案 2 :(得分:1)
你的服务不需要做任何“特殊”......他们的行为方式仍然相同。另一方面,您的客户端必须使用异步模式来使用服务。最简单的方法是使用“添加服务引用...”。只需检查一个显示“生成异步操作”的小方框,瞧,您可以对您的服务进行异步调用...
这是一个很好的资源:How to: Call WCF Service Operations Asynchronously
尽管有负面评论,最后的例子很好。只需订阅&lt; service-name&gt;已完成事件,然后进行异步调用。调用完成后,您的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! :)
}
}