我的同事在下面写了这段代码“closeConnection()”,并抛出了类型的异常:
检测到RaceOnRCWCleanup
已尝试释放正在使用的RCW。 RCW在 在活动线程或其他线程上使用。试图释放一个 使用中的RCW可能导致损坏或数据丢失。
private static void closeConnection()
{
if(connection != null)
{
try
{
connection.Close(); // <-- this is the problem
}
catch(Exception)
{
}
connection = null;
}
}
由于此代码包含在try {} catch {}块中,因此我得出结论,您无法捕获此类异常。是这种情况吗?
答案 0 :(得分:6)
这不是一个例外,它是一个调试器警告。它是“托管调试助手”之一,旨在捕捉可能导致以后很难诊断问题的常见错误。所以不,你不能用try / catch来捕获它。您可以使用Debug + Exceptions,Managed Debugging Assistants,“RaceOnRCWCleanup”的“Thrown”复选框将其关闭。
它可以是一个误报,但你应该担心这一点。通用诊断是connection.Close()调用导致释放COM对象。但它返回到由同一个COM对象启动的代码,通常是由于一个事件。这意味着它可能返回到COM服务器内的代码,该服务器是现在销毁的COM对象的一部分。如果这是服务器无法处理的事情,它通常会发出响亮的声音,通常是完全不可识别的AccessViolation。如果它没有爆炸并且你彻底测试了这个,那么继续并关闭警告。或者找一种方法稍后调用Close(),查看this answer以获取示例。
答案 1 :(得分:1)
您可能有竞争条件,多个线程可以同时输入您的方法。您需要锁定,以便2个线程不会同时输入相同的代码,例如。
public static classs SomeClass
{
private static object locker;
private static void closeConnection()
{
if(connection != null)
{
lock(locker)
{
if(connection != null) //might have been set to null by another thread so need to check again
{
try
{
connection.Close(); // <-- this should work now
}
catch(Exception)
{ //Don't swallow an exception here
}
connection = null;
}
}
}
}
RaceOnRCWCleanup不是例外,因此您无法捕获它,它是在CLR之外发生的触发调试器附件请求的事情。