WCF 暂停调用
Posted
技术标签:
【中文标题】WCF 暂停调用【英文标题】:WCF suspended call 【发布时间】:2014-03-26 20:25:35 【问题描述】:我有一个实现长轮询的 WCF 服务。但是,我认为没有办法让每个服务调用在被调用时产生一个新线程。
就目前而言,长轮询合约正在等待事件发生并阻止调用任何其他合约。
在 WCF 中让一个合同与另一个合同异步运行的推荐方法是什么?
我想保留一个静态线程池,但我不太确定该解决方案是否可扩展。
谢谢!
【问题讨论】:
【参考方案1】:在您的问题的上下文中,我假设 long-polling 是某种操作,它定期向第 3 方资源发出 HTTP 请求,直到返回所需的响应,或者直到超时。
为了有效地实现它,您可以使用 .NET 4.5、TAP pattern 和 async/await。
示例(未经测试):
// contract
[ServiceContract]
public interface IService
//task-based asynchronous pattern
[OperationContract]
Task<bool> DoLongPollingAsync(string url, int delay, int timeout);
// implementation
public class Service : IService
public async Task<bool> DoLongPollingAsync(
string url, int delay, int timeout)
// handle timeout via CancellationTokenSource
using (var cts = new CancellationTokenSource(timeout))
using (var httpClient = new System.Net.Http.HttpClient())
using (cts.Token.Register(() => httpClient.CancelPendingRequests()))
try
while (true)
// do the polling iteration
var data = await httpClient.GetStringAsync(url).ConfigureAwait(false);
if (data == "END POLLING") // should we end polling?
return true;
// pause before the next polling iteration
await Task.Delay(delay, cts.Token);
catch (OperationCanceledException)
// is cancelled due to timeout?
if (!cts.IsCancellationRequested)
throw;
// timed out
throw new TimeoutException();
这可以很好地扩展,因为大多数时候DoLongPolling
处于挂起状态,异步等待HttpClient.GetStringAsync
或Task.Delay
调用的结果。这意味着它不会阻塞来自ThreadPool
的线程,因此WCF 服务可以同时处理更多DoLongPolling
请求。查看 Stephen Cleary 的 "There Is No Thread",了解更多关于幕后工作原理的详细信息。
在客户端,您也可以异步调用 WCF 服务。在创建 WCF 服务代理时勾选“允许生成异步操作”并选择“生成基于任务的操作”。
如果您需要以 .NET 4.0 为目标,您可以在 Jaliya Udagedara 的 "Asynchronous Operations in WCF" 中找到一些替代选项。
【讨论】:
以上是关于WCF 暂停调用的主要内容,如果未能解决你的问题,请参考以下文章
利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复(转)
Postman Collection Run 确实会暂停 setTimeout 调用