2011-06-17 54 views
2

我有一個並行執行的任務;例如異步打印用戶選擇的文檔。一種方法可能是使用工作線程。但考慮到成千上萬的請求涌入Web服務器的情況,以及應用程序正在產生一個打印線程,這聽起來很可怕。如果所有的併發用戶都開始打印呢?使用Web Service避免線程的並行(異步)任務

所以是我想避免工作線程的原因。

爲了解決這個問題,我將代碼移到了一個web服務中;我打電話給PrintAsync()方法,並且我訂閱了OnPrintComplete以獲得通知。現在,我可以發送儘可能多的打印件,而無需擔心asp.net線程捱餓或阻塞請求。

我知道web服務內部使用線程,但這是IOCP線程,這意味着它不會打擾asp.net工作線程。

我想不出可能的缺點,除了它將是一個Web服務。

這是一個很好的方法嗎?本來應該是 更好 替代處理此功能的版本?

+4

什麼問題? – 2011-06-17 11:38:03

回答

4

所以你已經描述了你如何在客戶端上進行異步調用,實際上還有一些問題,我會問你如何在那裏完全異步,但是你的問題似乎更多的是關於如何在服務方面儘可能高效,對嗎?

如果您在服務操作中執行長時間運行或I/O綁定操作,那麼您必須必須開始利用WCF對asynchronous service operations的支持。現在,有很多方法可以做到這一點,但是如果您使用.NET 4.0,則沒有比使用Task Parallel Library(TPL)更好的方法。

首先,通過將工作卸載到TPL線程,釋放WCF I/O線程來處理更多的調用。這樣,長時間運行的WCF操作不會影響WCF執行其他操作的能力。

其次,TPL默認使用線程池。你不必擔心每一個操作都在旋轉它自己的線程,並最終導致資源耗盡。 TPL還足夠聰明,可以在沒有大量投資編寫管道代碼的情況下,以更高效的方式將工作分散到盒子上的所有核心。

第三,the TPL can be combined with the traditional Asynchronous Programming Model (APM)所以,如果你與像Streams事物(網絡或文件),則可以使用自己的BeginRead/Write方法利用異步I/O,以將騰出CPU線程而阻塞讀取最大/寫道。即使你沒有使用TPL,你也應該這樣做以達到最高的效率,TPL使它更容易。

這裏是你如何使用TPL來實現異步服務操作的「裸露的骨頭」的例子:

public IAsyncResult BeginSomeLongRunningOperation(string sampleParam, AsyncCallback callback, object asyncState) 
{ 
    Task<int> processingTask = Task<int>.Factory.StartNew(
     _ => 
     { 
      ... perform insanely long running operation here ... 

      return 42;  
     }, 
     asyncState); 

    // If there was a callback, we have to invoke it after the processing finishes 
    if(callback != null) 
    { 
     processingTask.ContinueWith(
      _ => 
      { 
       callback(calculationTask);     
      }, 
      TaskContinuationOptions.ExecuteSynchronously); 
    } 

    return processingTask; 
} 

public int EndSomeLongRunningOperation(IAsyncResult asyncResult) 
{ 
    return ((Task<int>)asyncResult).Result; 
} 
1

怎麼樣的微軟消息隊列(MSMQ)?

有了這種架構,您可以排隊所有打印請求,然後使用Windows服務來接收和處理。

建立和支持分佈式事務非常簡單。

MSMQ on MSDN