2012-01-12 95 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. 的单经理可以清理的过程中和/或使消费者报告其完成,对其进行清洁起来为好。