在WCF上调用dispose有多重要?和T通道对象后立即使用

本文关键字:对象 通道 调用 WCF dispose | 更新日期: 2023-09-27 18:04:44

开发人员喜欢编写尽可能简短和简单的代码。我们正在用c#调用WCF服务,想知道下面的直觉是对还是错。ChannelFactory码的一种使用方法是:

var factory = new ChannelFactory<IService>("Endpoint");
var client = factory.CreateChannel();
client.DoSomething();
((IClientChannel)client).Close();
factory.Close();

另一种方法(更干净一点)是使用包装器对象(对于工厂和通道),它实现了IDisposable,在using block中使用:

using (ServiceWrapper<IService> svcWrapper = new ServiceWrapper<IService>("Endpoint")) {
    svcWrapper.Channel.DoSomething();
}
在这里,必须调用包装器的属性对于开发人员来说可能有点烦人。基本上也可以是:
using (ServiceWrapper<IService> svcWrapper = new ServiceWrapper<IService>("Endpoint")) {
    IService client = svcWrapper.Channel;
    client.DoSomething();
}

(我还发现这篇MSDN文章说using块可以隐藏异常)

开发人员可能更喜欢的是:

 IService client = new ServiceWrapper<IService>("Endpoint").Channel;
 client.DoSomething();

摘自《c# 5.0概览》:

一个流行的模式是让终结器调用Dispose。这使得当清理不紧急时,通过调用Dispose来加速清理是一种优化,而不是必要的。

如果我把这个添加到我的ServiceWrapper (c# Finalize/Dispose模式):

public void Dispose() {
    Dispose(true);
    GC.SuppressFinalize(this);
}
~ServiceWrapper() {
    Dispose(false);
}

那么GC最终会调用Dispose并做需要做的事情。例如:

public void Dispose(bool disposing) {
    if (disposing) {
        if (_channel != null) {
            ((IClientChannel)_channel).Close();
        }
        if (_factory != null) {
            _factory.Close();
        }
        _channel = null;
        _factory = null;
    }
}

我有一种感觉,这不是一个很好的实践使用WCF ChannelFactory<T>T通道,但我没有一个很好的解释,这将吓跑开发人员使用它。你们能解释一下吗?

我不能说它不工作,我试过了,它工作得很好。我看不出任何明显的性能差异或类似……除了"您不知道何时调用终结器"之外,我无法给出其他解释。谢谢!

在WCF上调用dispose有多重要?和T通道对象后立即使用

那么,Dispose方法所做的唯一事情就是显式地关闭连接。就这些。您可以在参考源代码中自己看到。此外,ClientBase<T>,连接的基类也做同样的事情。

也就是说,如果您自己调用Close,那么目前根本没有实际需要调用Dispose,尽管我认为您确实应该调用Dispose,只是为了将来的证明。此外,这也可以作为错误发生的故障保护,这可能会阻止Close被调用。