2

我遇到了一个问题,ObjectDisposedException大约 50% 的时间都在抛出一个。try下面(内)内的代码finally导致异常。我不知道如何处理这个。我可以只吃异常,如下所示,但是有没有办法在不发生异常的情况下检查和关闭对象?

    public static FindResponse Discover(FindCriteria findCriteria, 
                                        DiscoveryEndpoint discoveryEndpoint = null)
    {
        DiscoveryClient discoveryClient = null;

        try
        {
            if (discoveryEndpoint == null) { 
                 discoveryEndpoint = new UdpDiscoveryEndpoint(); 
            }

            discoveryClient = new DiscoveryClient(discoveryEndpoint);

            return discoveryClient.Find(findCriteria);
        }
        finally
        {
            try
            {
                if (discoveryClient != null)
                {
                    discoveryClient.Close();
                }
            }
            catch (ObjectDisposedException)
            {
                // Eat it.
            }
        }
    }
4

3 回答 3

2

怎么样

public static FindResponse Discover(FindCriteria findCriteria, DiscoveryEndpoint discoveryEndpoint = null)
{
    if (discoveryEndpoint == null) 
      discoveryEndpoint = new UdpDiscoveryEndpoint();

    using (var client = new DiscoveryClient(discoveryEndpoint))
    {
        return client.Find(findCriteria);
    }
}

更新

似乎DiscoveryClient.Dispose()会抛出异常。OP 的原始方法似乎是唯一可以接受的答案。

于 2015-02-05T06:55:27.893 回答
1

虽然我不太清楚你为什么会遇到它,但你可以为普通的 WCF 客户端尝试以下操作:

如果您在 discoveryClient 上有可用的“State”属性,请尝试以下防御性检查:

finally
        {
            try
            {
                if (discoveryClient != null) 
                { 
                  if(discoveryClient.State == CommunicationState.Faulted)
                  {
                     discoveryClient.Abort();
                  }
                  else if(discoveryClient.State != CommunicationState.Closed )
                  {
                     discoveryClient.Close();
                  }
            }
            catch (ObjectDisposedException)
            {

            }
        }

希望这对您有所帮助。

于 2015-02-05T07:30:40.603 回答
-1

我还建议对 IDisposable 对象使用“使用”。考虑到 DiscoveryClient 是 IDisposable,

public static FindResponse Discover(FindCriteria findCriteria, DiscoveryEndpoint discoveryEndpoint = null)
    {

        FindResponse response = null;
        try
        {
            if (discoveryEndpoint == null) { discoveryEndpoint = new UdpDiscoveryEndpoint(); }

            using (DiscoveryClient discoveryClient = new DiscoveryClient(discoveryEndpoint))
            {
                response = discoveryClient.Find(findCriteria);
                discoveryClient.Close();
            }
        }
        finally
        {   
            // other finalizing works, like clearing lists, dictionaries etc.
        }
        return response;
    }
于 2015-02-05T06:58:41.297 回答