WCF暂停通话 [英] WCF suspended call

查看:225
本文介绍了WCF暂停通话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实现长轮询WCF服务。不过,我看不出有什么办法让在被称为每个服务调用生成一个新的线程。

I have a WCF service that implements long-polling. However, I see no way to have each service call spawn a new thread upon being called.

按照现在的情况,长轮询合同等待一个事件发生,并且是从被称为阻止任何其他合同。

As it stands, the long-polled contract is waiting for an event to occur and is blocking any other contracts from being called.

什么是推荐的方式有从WCF另一份合同?

What is the recommended way to have one contract run asynchronously from another contract in WCF?

我觉得保持一个静态的线程池,但我不是很确定,如果该解决方案的鳞片。

I thought of keeping a static thread pool but I'm not quite sure if that solution scales.

谢谢!

推荐答案

在你的问题的情况下,我假设的长轮询的是某种形式的操作是定期发出HTTP请求第三方资源,直到所需的响应已经返回,或直到超时。

In the context of your question, I assume long-polling is some kind of an operation which is periodically issuing an HTTP request to a 3rd party resource, until a desired response has been returned, or until timed out.

要有效地实现它,你可以使用.NET 4.5,抽头模式异步/计谋

To implement it efficiently, you can use .NET 4.5, TAP pattern and 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 调用。这意味着它不会阻止线程池一个线程,所以WCF服务可以兼任多个 DoLongPolling 请求。检查没有线程的通过斯蒂芬·克利里关于如何工作在幕后的更多细节。

This scales well, because most of the time the DoLongPolling is in the pending state, asynchronously awaiting the result of HttpClient.GetStringAsync or Task.Delay calls. Which means it doesn't block a thread from ThreadPool, so the WCF service can serve more DoLongPolling requests concurrently. Check "There Is No Thread" by Stephen Cleary for more details on how this works behind the scene.

在客户端,你可以异步调用WCF服务了。勾选允许生成异步操作当您创建的WCF服务代理,然后选择生成基于任务的操作。

On the client side, you can call your WCF service asynchronously, too. Tick "Allow generation of asynchronous operations" when you create the WCF service proxy and select "Generate task-based operations".

如果你需要的目标.NET 4.0中,你可以找到的异步操作的WCF通过Jaliya Udagedara。

If you need to target .NET 4.0, you can find some alternative options in "Asynchronous Operations in WCF" by Jaliya Udagedara.

这篇关于WCF暂停通话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆