【问题标题】:WCF suspended callWCF 暂停调用
【发布时间】:2014-03-26 20:25:35
【问题描述】:

我有一个实现长轮询的 WCF 服务。但是,我认为没有办法让每个服务调用在被调用时产生一个新线程。

就目前而言,长轮询合约正在等待事件发生并阻止调用任何其他合约。

在 WCF 中让一个合同与另一个合同异步运行的推荐方法是什么?

我想保留一个静态线程池,但我不太确定该解决方案是否可扩展。

谢谢!

【问题讨论】:

    标签: c# .net wcf asynchronous long-polling


    【解决方案1】:

    在您的问题的上下文中,我假设 long-polling 是某种操作,它定期向第 3 方资源发出 HTTP 请求,直到返回所需的响应,或者直到超时。

    为了有效地实现它,您可以使用 .NET 4.5、TAP patternasync/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" 中找到一些替代选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      相关资源
      最近更新 更多