正确关闭WCF 4通道的方法

chu*_*h97 11 c# wcf idisposable wcf-4

我使用以下方法关闭WCF 4通道.这是正确的方法吗?

using (IService channel 
    = CustomChannelFactory<IService>.CreateConfigurationChannel())
{
    channel.Open();

    //do stuff
}// channels disposes off??
Run Code Online (Sandbox Code Playgroud)

Enr*_*lio 20

曾经是在WCF"早期"发布WCF客户端代理的普遍接受的方式.

然而事情发生了变化.事实证明,IClientChannel <T> .Dispose()的实现只是调用IClientChannel <T> .Close()方法,这可能会在某些情况下抛出异常,例如底层通道未打开或可以'及时关闭.

因此,Close()catch块内调用并不是一个好主意,因为如果出现异常,可能会留下一些未发布的资源.

推荐的方法是调用IClientChannel <T> .Abort()的内catch块代替,在情况下Close()会失败.这是一个例子:

try
{
    channel.DoSomething();
    channel.Close();
}
catch
{
    channel.Abort();
    throw;
}
Run Code Online (Sandbox Code Playgroud)

更新:

以下是对描述此建议的MSDN文章的引用.

  • @Valentin 简短的回答是**是**,您*应该**明确*在不再需要时*发布WCF频道。一个开放的 WCF 通道包含一些较低级别的资源,例如 TCP 套接字或 HTTP 连接。如果您将这些资源留在垃圾收集器的*非确定性* 手中而延迟释放,您可能会遇到它们变得稀缺的情况,这将导致无法创建新通道。 (2认同)

tom*_*ern 8

虽然不是严格针对频道,但您可以这样做:

ChannelFactory<IMyService> channelFactory = null;
try
{
    channelFactory =
        new ChannelFactory<IMyService>();
    channelFactory.Open();

    // Do work...

    channelFactory.Close();
}
catch (CommunicationException)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
}
catch (TimeoutException)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
}
catch (Exception)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
    throw;
}
Run Code Online (Sandbox Code Playgroud)

  • 这个回答有点偏离:它提供了 ChannelFactory 的使用模式,而原始问题涉及通道。虽然(我相信)关闭工厂确实会关闭它创建的所有通道,但更常见的模式是保持通道工厂打开,以便它可以有效地创建多个通道。每个通道应单独关闭,同时保持工厂正常工作。 (5认同)