正确避免 ObjectDisposedException
Properly Avoid ObjectDisposedException
我 运行 遇到一个 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.
}
}
}
怎么样
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 的原始方法似乎是唯一可以接受的答案。
此外,我建议对 IDisposable 对象使用 "using"。考虑到 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;
}
虽然我不太清楚你为什么 运行 进入它,但你可以为普通的 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)
{
}
}
希望对您有所帮助。
我 运行 遇到一个 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.
}
}
}
怎么样
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 的原始方法似乎是唯一可以接受的答案。
此外,我建议对 IDisposable 对象使用 "using"。考虑到 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;
}
虽然我不太清楚你为什么 运行 进入它,但你可以为普通的 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)
{
}
}
希望对您有所帮助。