WCF编程工具是.NET Framework 3.5的重要组成部分,它独特的统一性,安全性以及兼容性可以帮助开发人员创造一个功能强大的企业级应用解决方案。其中,WCF异步调用是基于消息交换(Message Exchange)来实现的,和我们通常使用委托来实现异步调用有所不同。
WCF异步调用步骤1. 创建服务契约。
复制
[ServiceContract(SessionModeSessionMode=SessionMode.Required)] public interface ICalculate { [OperationContract] int Add(int a, int b); }
1.
2.
3.
4.
5.
6.
WCF异步调用步骤2. 为契约方法添加异步版本。
我们为 Add 方法添加了 BeginAdd 和 EndAdd 两个在 .NET SDK 中 "常见" 的异步操作方法。注意 BeginAdd 方法中我们添加了异步声明,而 EndAdd 方法没有。还有就是要注意异步版本方法的参数。
复制
[ServiceContract(SessionModeSessionMode=SessionMode.Required)] public interface ICalculate { [OperationContract] int Add(int a, int b); [OperationContract(AsyncPattern=true)] IAsyncResult BeginAdd(int a, int b, AsyncCallback callBack,
object state); int EndAdd(IAsyncResult ar); }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
WCF异步调用步骤3. 实现服务契约。
你可能注意到了,我们并没有创建 Add 的委托原型,也没有 "真正" 实现 BeginAdd 和 EndAdd。这是因为消息交换会 "异步" 调用 Add 方法,所有的异步版本方法只是用来创建消息声明而已。
复制
public class CalculateService : ICalculate { public int Add(int a, int b) { Thread.Sleep(5000); Console.WriteLine(OperationContext.Current.SessionId); return a + b; } public IAsyncResult BeginAdd(int a, int b, AsyncCallback
callBack, object state) { throw new Exception("The method or operation is not implemented."); } public int EndAdd(IAsyncResult ar) { throw new Exception("The method or operation is not implemented."); } }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
WCF异步调用步骤4. 我们给一个完整版本,看看执行结果。
复制
[ServiceContract] public interface ICalculate { [OperationContract] int Add(int a, int b); [OperationContract(AsyncPattern = true)] IAsyncResult BeginAdd(int a, int b, AsyncCallback callBack,
object state); int EndAdd(IAsyncResult ar); } public class CalculateService : ICalculate { public int Add(int a, int b) { Console.WriteLine("服务器方法 Add 开始执行: {0}", DateTime.Now); try { Thread.Sleep(5000); return a + b; } finally { Console.WriteLine("服务器方法 Add 执行完成: {0}", DateTime.Now); } } public IAsyncResult BeginAdd(int a, int b, AsyncCallback
callBack, object state) { throw new Exception("The method or operation is not implemented."); } public int EndAdd(IAsyncResult ar) { throw new Exception("The method or operation is not implemented."); } } public class WcfTest { public static void Test() { AppDomain.CreateDomain("Server").DoCallBack(delegate { ServiceHost host = new ServiceHost(typeof(CalculateService)); host.AddServiceEndpoint(typeof(ICalculate), new WSHttpBinding(), "http://localhost:8080/calc"); host.Open(); }); ICalculate channel = ChannelFactory<ICalculate>.CreateChannel
(new WSHttpBinding(), new EndpointAddress("http://localhost:8080/calc")); using (channel as IDisposable) { Console.WriteLine("客户端调用 BeginAdd: {0}", DateTime.Now); IAsyncResult ar = channel.BeginAdd(1, 2, delegate
{ Console.WriteLine("CallBack..."); }, null); Console.WriteLine("客户端调用 BeginAdd 完成: {0}", DateTime.Now); Console.WriteLine(channel.EndAdd(ar)); Console.WriteLine("客户端调用 EndAdd 完成: {0}", DateTime.Now); } } }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
输出:
复制
客户端调用 BeginAdd: 2007-4-1 20:56:47 客户端调用 BeginAdd 完成: 2007-4-1 20:56:47 服务器方法 Add 开始执行: 2007-4-1 20:56:49 服务器方法 Add 执行完成: 2007-4-1 20:56:54 3 客户端调用 EndAdd 完成: 2007-4-1 20:56:55 CallBack...
1.
2.
3.
4.
5.
6.
7.
最后在WCF异步调用步骤中需要注意的是,我们必须使用支持 Session 的 Binding 对象 (BasicHttpBinding 会抛出异常)。
【编辑推荐】