【发布时间】:2015-10-17 07:20:18
【问题描述】:
开发人员喜欢编写尽可能简短的代码。我们在 C# 中调用 WCF 服务,并想知道以下直觉是对还是错。
使用ChannelFactory 代码的一种方式是:
var factory = new ChannelFactory<IService>("Endpoint");
var client = factory.CreateChannel();
client.DoSomething();
((IClientChannel)client).Close();
factory.Close();
其他方式(更简洁一些)是使用包装器对象(用于工厂和通道),它实现了IDisposable,其中同时配置并用于 using 块:
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();
}
(我还发现this MSDN article说using块可以隐藏异常)
开发人员可能更喜欢的是:
IService client = new ServiceWrapper<IService>("Endpoint").Channel;
client.DoSomething();
摘自《C# 5.0 in a Nutshell》一书:
一种流行的模式是让终结器调用 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 通道一起使用的好习惯,但我没有一个很好的解释,这会吓跑开发人员使用它。能解释一下吗?
我不能说它不起作用,我试过了,它工作正常。我看不到任何明显的性能差异或类似... 除了“你不知道终结器何时被调用”之外,我无法给出其他解释。 谢谢!
【问题讨论】: