简体   繁体   English

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

[英]How important is to call dispose on a WCF ChannelFactory<T> and T channel object right after usage?

Developers like to write as short and simple code as possible. 开发人员喜欢尽可能简短地编写代码。 We are invoking WCF services in C# and wondering if the following intuition is right or wrong. 我们在C#中调用WCF服务,并想知道以下直觉是对还是错。 One way of using ChannelFactory code is: 使用ChannelFactory代码的一种方法是:

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

client.DoSomething();

((IClientChannel)client).Close();
factory.Close();

Other way (a bit cleaner) is using a wrapper object (for factory and channel) which implements IDisposable where disposes both and used in using block: 其他方式(更清洁)是使用包装器对象(用于工厂和通道)实现IDisposable ,其中两者都配置并用于使用块:

using (ServiceWrapper<IService> svcWrapper = new ServiceWrapper<IService>("Endpoint")) {
    svcWrapper.Channel.DoSomething();
}

Here, having to call the wrapper's property might be a bit annoying for developers. 在这里,不得不调用包装器的属性对开发人员来说可能有点烦人。 Basically also could be: 基本上也可能是:

using (ServiceWrapper<IService> svcWrapper = new ServiceWrapper<IService>("Endpoint")) {
    IService client = svcWrapper.Channel;
    client.DoSomething();
}

(I also found this MSDN article saying that the using block can hide exceptions) (我也发现这篇MSDN文章说使用块可以隐藏异常)

What the developers might prefer is: 开发人员可能更喜欢的是:

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

From the book C# 5.0 in a Nutshell: 从Nutshell中的C#5.0一书:

A popular pattern is to have the finalizer call Dispose. 一种流行的模式是让终结器调用Dispose。 This makes sense when cleanup is non-urgent and hastening it by calling Dispose is more of an optimization than a necessity. 当清理非紧急并通过调用来加速它时,这是有道理的。更多的是优化而非必需。

If I add this to my ServiceWrapper (C# Finalize/Dispose pattern): 如果我将它添加到我的ServiceWrapper (C#Finalize / Dispose模式):

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

~ServiceWrapper() {
    Dispose(false);
}

Then GC will eventually call Dispose and do the things that need to be done. 然后GC最终会调用Dispose并完成需要完成的事情。 ie: 即:

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

        _channel = null;
        _factory = null;
    }
}

I have a feeling that this is not a good practice to use with WCF ChannelFactory<T> and T channel, but I don't have a good explanation which would scare the developers away form using it. 我觉得这不适合与WCF ChannelFactory<T>T频道一起使用,但我没有一个很好的解释,它会吓跑开发人员使用它。 Can you guys explain pls? 你能解释一下吗?

I can't say it's not working, I tried it and it works fine. 我不能说它不起作用,我试过它并且工作正常。 I can't see any noticeable performance difference or similar... I cannot give other explanation than "You don't know when the finalizer gets called." 我看不出任何明显的性能差异或类似的...我不能给出其他解释而不是“你不知道何时调用终结器”。 Thanks! 谢谢!

Well, the only thing the Dispose method does is explicitly close the connection. 好吧, Dispose方法唯一做的就是显式关闭连接。 That is all. 就这些。 You can see for yourself in the reference source . 您可以在参考源中看到自己。 Also, ClientBase<T> , the base class for the connection does the same. 此外, ClientBase<T> ,连接的基类也是如此。

That said, if you call Close yourself there isn't an actual need at the moment to call Dispose at all, although I would argue that you really should Dispose , just to be future proof. 也就是说,如果你自己打电话给Close目前根本没有实际需要调用Dispose ,虽然我认为你真的应该Dispose ,以便将来证明。 Also this can be a fail-safe for errors occurring which may prevent Close to be called. 此外,这可能是发生错误的故障保护,可能会阻止调用Close

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM