65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF 操作超时异常

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.45/5 (20投票s)

2008年7月31日

CPOL

3分钟阅读

viewsIcon

223784

WCF 操作超时异常

引言

WCF 客户端通过以下主要活动与 WCF 主机服务交互

  • 地址(服务的位置,例如:http://net.tcp://
  • 契约(客户端和服务器之间的类接口)
  • 绑定(客户端和服务器之间通过编码和协议进行传输)

WCF 配置

应通过 SVCConfigEditor.exe 为客户端和服务器应用程序完成 WCF 配置。 服务和客户端端点配置应分别在客户端和服务器的 app.config 中完成。 通常,对于客户端服务器应用程序,应使用 NetTcp 完成绑定。 此 NetTcp 绑定配置应在客户端和服务器 app.config 服务模型的 bindings 部分中指定。 需要在绑定中指定几个超时配置,例如 CloseTimeoutOpenTimeoutReceiveTimeoutSendTimeout。 默认情况下,所有这些绑定超时的超时持续时间设置为 1 分钟 (00:01:00)。 此外,ReliableSession 还需要 InactivityTimeout 配置。 会话不活动的默认超时持续时间为 10 分钟 (00:10:00)。 当客户端从服务主机调用服务时,这些值将从应用程序中获取。

代码实现

创建服务契约和操作契约方法(接口)

<ServiceContract()> _
 Public Interface IntrWCFOprContr
 <OperationContract()> _
 Function CheckForService() As Boolean
 End Interface

接口实现

Public Class ClsWCFImpl
 Implements IntrWCFOprContr
 Public Function CheckForService () As Boolean _
 Implements IntrWCFOprContr.CheckForService
 'Business Logic Code/Calls goes here
 'Database calls goes here
End Function

WCF 客户端 (VB.NET Windows 应用程序)

'Importing WCFoperation namespace which has ClsWCFImpl
 Imports WCFOperation
Private Sub frmWCFClient_Load(ByVal eventSender As System.Object,
  ByVal eventArgs As System.EventArgs) Handles MyBase.Load
'Instantiating Channel Factory
Using serviceinvoke As New ChannelFactory(Of ClsWCFImpl)(New NetTcpBinding,
  "net.tcp://:4001/ClsWCFImpl ")
Try
 Dim service As ClsWCFImpl
 service = serviceinvoke.CreateChannel()
 If serviceinvoke.State = CommunicationState.Opened Then
   If service.CheckForService() then
   'Your code goes here
   Else
     'Your code goes here
   End If
 End If
Catch ex As TimeoutException
 'System.Diagnostics.Debug.Assert(False, "")
 'Debug.Assert(False, "")
 Trace.WriteLine("An exception of type '" + ex.GetType().ToString() _
 + " occurred " _
 + ex.Message, "Exceptions")
 End Try
 End Using
 End Sub

WCF 服务主机 (Windows 服务)

'Code in Service1.vb to create and open service host
Imports WCFOperation
Public TheHost As ServiceHost
Protected Overrides Sub OnStart(ByVal args() As String)
 Try
 If TheHost Is Nothing Then
  TheHost = New ServiceHost(GetType(ClsWCFImpl))
  TheHost.Open()
 End If
 Catch ex As CommunicationObjectFaultedException
  Trace.WriteLine("An exception of type '" + ex.GetType().ToString() _
  + "occurred while OnStart Function in WCF Service. The message of the exception is: " _
  + ex.Message, "Exceptions")
 End Try
End Sub

Protected Overrides Sub OnStop()
Try
 Trace.WriteLine("Windows Service - OnStop " & Date.Now.ToString, "Informational")
 If TheHost IsNot Nothing Then
  TheHost.Close()
 End If
 ' 03/25/2008 - Added code to log Informational messages
End Try
End Sub

工作原理

上面的代码表示托管在 Windows 服务中的 WCF 客户端 Windows 应用程序。 WCF 客户端将检查主机状态。 如果主机已打开(服务正在运行),则 WCF 客户端和服务主机之间通过提到的端点地址开始通信。 只要数据库调用没有延迟,例如执行存储过程、查询以及使用 Dataadapter 填充 DataTableDataSet,以上示例就可以使用默认 WCF 配置正常工作。

问题

在以下情况下,相同的代码示例将引发 操作超时错误

  • 如果数据库响应延迟超过一分钟
  • OLEDB/SQL/ODBC 命令执行
  • Dataadapter.Fill,使用 DataTableDataSet
  • 使用 DataReader 读取数据

延迟可能发生在许多方面,例如从数据库执行、从不同层执行业务逻辑、从应用程序中引用的其他接口延迟响应。 由于这些延迟,WCF 客户端从 WCF 主机进入空闲状态。 如果客户端从 WCF 服务进入空闲状态,它将抛出以下错误。

Error(错误)

在 ' 函数' 中发生类型为 'System.TimeoutException' 的异常。 异常的消息是:发送到 net.tcp://:4001/ ClsWCFImpl 的此请求操作未在配置的超时 (00:01:00) 内收到回复。 分配给此操作的时间可能是一个较长超时的一部分。 这可能是因为服务仍在处理该操作,或者服务无法发送回复消息。 请考虑增加操作超时(通过将通道/代理强制转换为 IContextChannel 并设置 OperationTimeout 属性),并确保服务能够连接到客户端。

解决方案

为了避免此超时错误,我们需要在 WCF 客户端代码中为代理配置 OperationTimeout 属性。 这种配置是全新的,不同于发送超时、接收超时等其他配置,我在文章前面讨论过。 为了设置此操作超时属性配置,我们必须在调用操作契约方法之前,在 WCF 客户端应用程序中将我们的代理强制转换为 IContextChannel。 在这里,我重复相同的 WCF 客户端 Windows 应用程序代码,并在黄色中突出显示了操作超时更改

Imports WCFOperation
Private Sub frmWCFClient_Load(ByVal eventSender As System.Object,
  ByVal eventArgs As System.EventArgs) Handles MyBase.Load
'Instantiating Channel Factory
Using serviceinvoke As New ChannelFactory(Of ClsWCFImpl)(New NetTcpBinding,
  "net.tcp://:4001/ClsWCFImpl ")
Try
  Dim service As ClsWCFImpl
  service = serviceinvoke.CreateChannel()
  If serviceinvoke.State = CommunicationState.Opened Then
    'Casting the Proxy with IContextChannel and set the Operation timeout property
    'with the time duration in seconds
    DirectCast(service, IContextChannel).OperationTimeout = New TimeSpan(0, 0, 240)
    If service.CheckForService() then
      'Your code goes here
    Else
      'Your code goes here
    End If
  End If
  Catch ex As TimeoutException
  'System.Diagnostics.Debug.Assert(False, "")
  'Debug.Assert(False, "")
  Trace.WriteLine("An exception of type '" + ex.GetType().ToString() _
  + " occurred " _
  + ex.Message, "Exceptions")
End Try
End Using
End Sub

在这里,超时持续时间设置为 240 秒。 持续时间也可以根据应用程序中的需求以及数据库或其他接口响应的预期临时延迟,设置为小时或分钟格式。 最好将超时持续时间保存在应用程序的 app.config 中,并在需要时不断更改它。

结论

此操作超时配置适用于能够以指定持续时间连接到客户端的服务。 当在托管的 .NET 应用程序(例如控制台或 Web 应用程序 (ASP.NET))中托管 WCF 时,也适用相同的解决方案。

祝你一切顺利!!!

历史

  • 2008 年 7 月 31 日:初始帖子
© . All rights reserved.