2012-01-12 124 views
2

我們有一個應用程序將一個對象(本例中爲「printJob」)發送給服務。根據我們的交易量,這個過程可能需要一段時間。一旦服務完成了它的工作,它就會嚮應用程序返回一個「PrintJobID」。WCF超時問題

PrintGatewayClient printClient = new PrintGatewayClient(); 
PrintService.ServiceJob printJob = new PrintService.ServiceJob(); 
printJob.ServicePrintItems = checkList.ToArray(); 

try 
{ 
    currentBatch.PrintJobID = printClient.SubmitPrintJob(printJob); 
    PaymentBatchesGateway.Update(currentBatch); 
} 
catch (System.Exception ex) 
{ 
    throw ex; 
} 

printClient.Close(); 

的appliation等待,等待printClient來完成它的工作並領取「PrintJobID」的整數然後更新一個表,該ID。然而,當大批量的跑了,我們得到以下錯誤:

The request channel timed out while waiting for a reply after 00:04:59.9062464. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. 

我已經看過我們的web.config文件在NetTcpBinding的:

<netTcpBinding> 
    <binding name="NetTcpBinding_IPrintGateway" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="02:00:00" sendTimeout="02:00:00" 
     transactionFlow="false" transferMode="Buffered" 
     transactionProtocol="OleTransactions" 
     hostNameComparisonMode="StrongWildcard" listenBacklog="10" 
     maxBufferPoolSize="524288" maxBufferSize="50000000" maxConnections="10" 
     maxReceivedMessageSize="50000000"> 

    <readerQuotas maxDepth="5000" maxStringContentLength="150000" 
     maxArrayLength="16384" maxBytesPerRead="50000000" 
     maxNameTableCharCount="16384" /> 

    <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> 
    <security mode="None"> 
      <transport clientCredentialType="None" protectionLevel="None" /> 
      <message clientCredentialType="None" /> 
    </security> 
    </binding> 
<netTcpBinding> 

<client> 
    <endpoint address="http://server/printgateway/PrintGateway.svc" 
     binding="basicHttpBinding" 
     bindingConfiguration="BasicHttpBinding_IPrintGateway" 
     contract="PrintService.IPrintGateway" 
     name="BasicHttpBinding_IPrintGateway" />  
</client> 

我無法找到一個超時的00 :05:00在代碼中的任何地方。任何人都可以請解釋並告訴我如何延長這個時間。我可以在代碼中,在web.config中,在服務器上執行此操作嗎?

謝謝!

+0

我不是特別WCF知識淵博,我不知道哪裏有5分鐘的超時是從哪裏來的。然而,對於測試,你有沒有嘗試增加你的closeTimeout,openTimeout,receiveTimeout,和值的SendTimeout的東西要高得多,如果expception仍然出現看?我也相信你可以創建一個合適的綁定對象,設置binding.SendTimeout = TimeSpan.FromMinutes(60); (以及其他超時值),並在創建服務客戶端時使用該對象。 – Dan 2012-01-12 17:41:24

回答

1

在一個服務調用上有一個線程塊,等待60秒的響應時間過長,代表了糟糕的設計選擇。你肯定不想把這個增加到5分鐘,如果5分鐘,爲什麼不是一個小時?這不是一個現實的或可支持的解決方案。

改爲使用異步服務調用會好得多。

當您將服務引用添加到項目時,請在添加服務引用對話框中單擊高級,然後在客戶端下選擇「生成異步操作」。由此生成的代理類將爲服務合約中的每個OperationName使用[OperationName] Completed事件和and [OperationName]異步方法。一旦回覆的訊息已經被WCF基礎設施接收

var client = new Service1Client(); 
    client.GetDataCompleted += Client_GetDataCompleted; // specify the callback method 
    client.GetDataAsync(0); 
    // ... 


static void Client_GetDataCompleted(object sender, GetDataCompletedEventArgs e) 
{ 
    var response = e.Result; 
    // ... 
} 

回調方法被安排在一個線程。更多「如何:異步調用WCF服務操作」http://msdn.microsoft.com/en-us/library/ms730059.aspx

+0

不幸的是,我繼承了離開公司的其他開發人員的應用程序。我只是支持應用程序。你能解釋一下「異步服務調用」是什麼意思嗎? – Turp 2012-01-12 18:30:56

+0

Wcf不會阻止,因爲單個實例爲客戶端服務的時間過長。默認行爲是產生另一個實例來提供新的請求。但儘管如此異步服務可能是一個好主意,它只是將不會解決超時問題,因爲服務器仍然需要做其工作,以便它可能是一個更好的主意來解決性能問題。如果服務器處理大量數據傳輸或預計長時間運行的類似任務,那麼提高超時也是可以的。 – faester 2012-01-12 19:32:20

+0

@faester,您確定每個調用實例都是WCF中服務的默認實例化模型。這裏顯示的代碼是客戶端代碼。客戶端會阻止,而不是服務。某些服務操作(如業務流程操作)可能需要很長時間(數小時,數週)才能完成並返回響應消息。客戶端選擇同步調用服務(等待響應的線程塊)或異步調用(線程不會阻塞等待響應)。 – 2012-01-12 22:54:38

1

有兩個配置文件,一個在服務端,一個在消費端。它看起來像你有消費者配置。您可能會在服務配置中找到5分鐘的超時設置。

但是,我同意Visual Stuart認爲長時間等待同步服務調用是不可取的。應該發生的情況是打印作業被添加到隊列中,並且在它們被處理之後,可以將響應發送給呼叫用戶。

然而,這將代表重大的重建努力。

1

對於啓動業務邏輯的Silverlight控件,我們有類似的情況,這取決於選擇哪些操作會導致超時。我實現了一個投票的情況,如下面

  1. 調用StartOperation WCF服務方法,該方法返回一個唯一的ID給消費者。
  2. 該服務方法啓動後臺進程,該進程完成工作並簡單報告狀態。
  3. 消費者使用唯一標識調用獨立的wcf服務狀態方法以獲取狀態。
  4. 狀態方法檢查後臺進程(I中使用的單管理器,它有一箇中查找字典正在運行的進程),並返回其狀態。
  5. 消費者要求#3,直到完成報告。它報告完成後
  6. 的單經理可以清理的過程中和/或使消費者報告其完成,對其進行清潔起來爲好。