异步
此异步示例演示客户端如何以异步方式访问服务操作,以及服务如何以异步方式实现其操作。此示例基于实现计算器服务的入门示例。是使用同步调用还是异步调用只是一个本地决策,而不会影响在网络上发送的消息。尽管服务实现了一些同步操作,但是客户端仍能够以异步方式访问服务操作。尽管客户端以同步方式调用服务,但是服务仍能够以异步方式实现某些操作。
注意: |
---|
本主题的最后介绍了此示例的设置过程和生成说明。 |
在此示例中,客户端是一个控制台应用程序 (.exe),而且服务自承载在控制台应用程序 (.exe) 中。
服务实现 ICalculator
接口。客户端可以在该接口上以异步方式调用操作,这意味着 Add
之类的操作现在具有 BeginAdd
和 EndAdd
。
注意: |
---|
有关异步模式的更多详细信息,请参见 .NET Framework 文档。 |
客户端已经生成了支持这些异步操作的代码。客户端是通过运行带 /a (async)
命令选项的ServiceModel 元数据实用工具 (Svcutil.exe) 工具来创建的,如下所示:
svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35
Add
操作的服务协定的客户端异步版本看上去类似于下面的代码。
[System.ServiceModel.ServiceContractAttribute(Namespace=
"http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[System.ServiceModel.OperationContractAttribute(
AsyncPattern=true)]
System.IAsyncResult BeginAdd(double n1, double n2,
System.AsyncCallback callback, object asyncState);
double EndAdd(System.IAsyncResult result);
...
}
当同时指定 /tcv:Version35
选项和 /async
选项时,所生成的客户端类型将实现用来调用服务且基于事件的异步模式。有关信息,请参见基于事件的异步模式概述(可能为英文网页)。若要以异步方式访问服务操作,应用程序需要在客户端上向 [Operation]Completed
事件添加事件处理程序,然后调用 [Operation]Async
方法(例如,AddAsync
),如下面的示例代码中所示。
// Create a client.
CalculatorClient client = new CalculatorClient();
// BeginAdd.
double value1 = 100.00D;
double value2 = 15.99D;
client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);
在该示例中,客户端以异步方式启动两个操作:Add
和 Subtract
。
在执行回调函数时,客户端会访问 [Operation]CompletedEventArgs
输入参数上的 Result
属性以检索结果。
static void AddCallback(object sender, AddCompletedEventArgs e)
{
Console.WriteLine("Add Result: {0}", e.Result);
}
所有的异步行为都发生在客户端本地,而且不会影响客户端发出消息的方式或服务处理消息的方式。在用户界面 (UI) 应用程序中使用此模式的通常原因是为了释放 UI 线程以便更新屏幕。当服务充当客户端,而且您希望消息处理线程不再调用其他服务时,此模式也适用。下一节将演示如何将服务操作设置为异步操作。
服务实现 ICalculator
接口,如下面的代码中所示。
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginMultiply(double n1, double n2,
AsyncCallback callback, object state);
double EndMultiply(IAsyncResult ar);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginDivide(double n1, double n2,
AsyncCallback callback, object state);
double EndDivide(IAsyncResult ar);
}
该协定的前两个操作由 Windows Communication Foundation (WCF) 运行库以同步方式调用。最后两对操作用来以异步方式调用服务。此示例将 AsyncPattern 属性设置为 true。此属性设置与 .NET Framework 异步模式的实现一起,通知运行库以异步方式调用该操作。
在服务实现中使用此模式的原因在于,在执行需要花费大量时间的输入和输出操作(如访问磁盘、访问数据库或调用另一个服务)时,通常需要释放消息处理线程。此示例演示如何用 IAsyncResult 的实现来包装文件的输入和输出操作。在编写自己的 IAsyncResult
实现时,可以重用 MathAsyncResult
类的实现的基类。
注意: |
---|
此示例使用 PerCall 和 Multiple 来防止出现会话绑定随附的排序行为。默认情况下,wsHttpBinding 使用会话来建立安全上下文。这不会影响客户端或服务上消息处理的异步性质,但是它会将重点放在对响应的计时上,而且会允许客户端遵循并发(而不是依次)回调。 |
运行示例时,操作的请求和响应将显示在客户端控制台窗口中。Add
和 Subtract
请求不会阻止,因为它们是以异步方式调用的。之后,Multiply
和 Divide
运算将阻止,它们的结果将在请求发出的同时显示出来。最后,当这些结果返回到客户端时,Add
和 Subtract
运算的结果将显示出来。sleep
在服务的 Add
和 Subtract
实现中用来显示客户端上的异步回调。
Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Add Result: 115.99
Subtract Result: 68.46
线程 ID 在服务上用来演示同步调用(如 Add
和 Subtract
)是在单个线程上处理的。异步调用(如 Multiply
和 Divide
)会涉及多个线程。服务的输出看上去如下所示。
Received Add Synchronously on ThreadID 11: Sleeping for 3 seconds
Asynchronous call: BeginMultiply on ThreadID 12
Received Subtract Synchronously on ThreadID 12: Sleeping for 3 seconds
IO thread for * operation on ThreadID 13
EndMultiply called on ThreadID 14
Asynchronous call: BeginDivide on ThreadID 14
IO thread for / operation on ThreadID 13
EndDivide called on ThreadID 14
Returning Add Result on ThreadID 11
Returning Subtract Result on ThreadID 12
.NET Framework 异步模式可以在客户端和/或服务上使用。如该示例中所示,这两端是相互独立的。
设置、生成和运行示例
若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照生成 Windows Communication Foundation 示例中的说明进行操作。
若要用单机配置或跨计算机配置来运行示例,请按照Running the Windows Communication Foundation Samples中的说明进行操作。
注意: |
---|
您的计算机上可能已安装这些示例。在继续操作之前,请先检查以下(默认)目录。
<安装驱动器>:\WF_WCF_Samples
如果此目录不存在,请访问针对 .NET Framework 4 的 Windows Communication Foundation (WCF) 和 Windows Workflow Foundation (WF) 示例(可能为英文网页),下载所有 Windows Communication Foundation (WCF) 和 WF 示例。此示例位于以下目录。
<安装驱动器>:\WF_WCF_Samples\WCF\Basic\Contract\Service\Asynchronous
|