WCF:使用分部类覆盖客户端的Dispose方法是否安全?

时间:2010-04-08 22:08:13

标签: c# .net wcf

我想覆盖生成的代理(ClientBase)的Dispose方法,因为处理代理会调用Close,并且当通道出现故障时可能会抛出异常。

我提出的唯一方法是为我生成的代理创建一个部分类,使其继承自IDisposable

 public partial class MyServiceProxy : IDisposable
    {
        #region IDisposable Members

        public void Dispose()
        {
            if (State != System.ServiceModel.CommunicationState.Faulted)
                Close();
            else
                Abort();
        }

        #endregion
    }

我做了一些测试,确实调用了我的Dispose方法。

您认为此策略存在任何问题吗?

另外,我不喜欢我必须为每个生成的代理创建这个分部类的事实。

如果我能够从基类继承代理,那就太好了......

2 个答案:

答案 0 :(得分:2)

它没有问题。以这种方式自定义设计器生成的代码正是部分类要提供的功能,这是处理IDisposable上损坏的ClientBase实现的推荐方法之一。

至于必须为每个WCF客户端重新实现此代码 - 不幸的是,如果您想使用IDisposable模式,那么您将会这样做。您可以将if/else块提取到实用程序方法中,但仍然需要为每个块创建一个部分类并覆盖Dispose

看到上述内容相当繁琐,许多人选择使用Service Proxy Helper,因为它不需要编写任何新代码。

我使用稍微修改过的版本,我自己:

public static class Service<TProxy>
    where TProxy : ICommunicationObject, IDisposable, new()
{
    public static void Using(Action<TProxy> action)
    {
        TProxy proxy = new TProxy();
        bool success = false;
        try
        {
            action(proxy);
            proxy.Close();
            success = true;
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }
    }
}

允许编写这种代码:

Service<MyServiceClient>.Using(svc => svc.PerformOperation());

或者:

Service<MyServiceClient>.Using(svc =>
{
    var result = svc.PerformOperation();
    ProcessResult(result);
});

注意:WCF代理的创建成本很高,因此您通常希望尽可能长时间地保持它们的存活,而不是每隔几秒(或更多)创建和处理它们。这适用于不经常使用的客户端。

答案 1 :(得分:1)

重写Dispose()方法是一种完全有效的策略。

此问题的答案中还有其他一些选项:What is the best workaround for the WCF client `using` block issue?