我有一個WCF服務實現長輪詢。但是,我沒有辦法讓每個服務調用在被調用時產生一個新線程。WCF暫停呼叫
就目前而言,長期投票的合約正在等待事件發生並阻止任何其他合約被調用。
什麼是推薦的方式讓一個合同與WCF中的另一個合同異步運行?
我想保持一個靜態線程池,但我不太確定該解決方案的規模。
謝謝!
我有一個WCF服務實現長輪詢。但是,我沒有辦法讓每個服務調用在被調用時產生一個新線程。WCF暫停呼叫
就目前而言,長期投票的合約正在等待事件發生並阻止任何其他合約被調用。
什麼是推薦的方式讓一個合同與WCF中的另一個合同異步運行?
我想保持一個靜態線程池,但我不太確定該解決方案的規模。
謝謝!
在你的問題的上下文中,我假設長輪詢是一種操作,它定期向第三方資源發出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"中找到其他選項。