2014-02-24 171 views
3

我有一個WCF服務實現長輪詢。但是,我沒有辦法讓每個服務調用在被調用時產生一個新線程。WCF暫停呼叫

就目前而言,長期投票的合約正在等待事件發生並阻止任何其他合約被調用。

什麼是推薦的方式讓一個合同與WCF中的另一個合同異步運行?

我想保持一個靜態線程池,但我不太確定該解決方案的規模。

謝謝!

回答

1

在你的問題的上下文中,我假設長輪詢是一種操作,它定期向第三方資源發出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"中找到其他選項。