我是WCF的新手.我正在制作一项服务,我需要在其中计算冗长的操作.由于该方法很长,我以为我可以通过返回一个Task来使操作异步.但它不起作用.我还在收到Timeout异常.示例代码(不是我的实际代码)演示了我的问题如下:
[ServiceContract]
public interface ICalculator
{
[OperationContract]
Task<double> ComputePiAsync(ulong numDecimals);
}
internal class Calculator : ICalculator
{
public async Task<double> ComputePiAsync(ulong numDecimals)
{
return await SomeVeryVeryLongWayOfComputingPi(numDecimals);
}
}
// server
using (var host = new ServiceHost(typeof(Calculator), new Uri("net.pipe://localhost")))
{
host.AddServiceEndpoint(typeof(ICalculator), new NetNamedPipeBinding(), "Calculator");
host.Open();
Console.WriteLine("Service is running. Press <ENTER> to exit.");
Console.ReadLine();
host.Close();
}
// client
var factory = new ChannelFactory<ICalculator>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/Calculator"));
var calculator = factory.CreateChannel();
await calculator.ComputePiAsync(numDecimals); // <--- this call takes longer than 1 minute and I'm getting a timeout here.
Run Code Online (Sandbox Code Playgroud)
那么,为了在我的服务上调用冗长的操作并异步等待结果,我该怎么办?增加超时?如果我增加操作超时,那么该方法返回任务的重点是什么?
YK1*_*YK1 16
由于该方法很长,我以为我可以使操作异步
坚持,慢下来 - 你正在混淆与网络操作超时的异步.
让我们先考虑异步:
1. async/await用于从客户端异步调用WCF服务
async/await在客户端帮助我们编写异步程序,以便应用程序保持响应 - 如果WPF/WinForm我们不希望通过在UI线程上同步调用WCF服务来冻结UI.相反,我们可以使用异步调用它async/await.这里神奇的是,这是完整的客户端功能-这意味着该服务不需要异步或不需要返回Task-所有你需要的就是在创建service reference(proxy)你要告诉Visual Studio生成Task基于异步操作-然后你可以使用async/await上你的客户.
那么async/await服务方面需要什么?
服务本身可以执行一些I/O类似查询的某些数据源,或者转而调用另一个服务.通过async/await在服务端使用- 服务可以异步执行这些操作 - 不会阻塞任何服务线程.这意味着服务有更多的免费线程来为新客户服务 - 因此服务规模要好得多.
现在,上面两个不应该与长时间运行的服务操作混淆
当您的服务需要很长时间才能获得结果时,您正在处理网络超时.您不能也不应该尝试在没有任何活动的情况下无限期地保持网络连接.WCF通过配置各种超时来帮助您.如果您的服务方法需要很长时间才能响应,则必须增加这些超时.WCF callback contracts如果要将进度报告回客户端,可以考虑使用.如果这不足以满足您的要求,则重新设计您的服务,以便客户端可以启动长时间运行的进程,然后调用服务上的另一个方法来查询状态.
| 归档时间: |
|
| 查看次数: |
4218 次 |
| 最近记录: |