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.GetStringAsyncTask.Delay 调用的结果。这意味着它不会阻塞来自ThreadPool 的线程,因此WCF 服务可以同时处理更多DoLongPolling 请求。查看 Stephen Cleary 的 "There Is No Thread",了解更多关于幕后工作原理的详细信息。

在客户端,您也可以异步调用 WCF 服务。在创建 WCF 服务代理时勾选“允许生成异步操作”并选择“生成基于任务的操作”。

如果您需要以 .NET 4.0 为目标,您可以在 Jaliya Udagedara 的 "Asynchronous Operations in WCF" 中找到一些替代选项。

【讨论】:

以上是关于WCF 暂停调用的主要内容,如果未能解决你的问题,请参考以下文章

需要定期暂停 Carousel 动画并调用一个函数

利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复(转)

BizTalk Server 2013 休息错误处理

Postman Collection Run 确实会暂停 setTimeout 调用

是否允许在暂停的进程上调用 CreateRemoteThread()?

使用 MPRemoteCommandCenter 时未调用播放/暂停回调