与this question类似,我有一个带有私有ManualReset事件的类:
class A {
private ManualResetEvent mre = new ManualResetEvent(true);
private void Method(){
//do something
mre.Reset();
}
public bool WaitForItem(int timeout){
try{
return mre.WaitOne(timeout)
}catch(ObjectDisposedException){
return false;
}
}
public void Dispose(){
mre.Dispose();
}
}
如何在调用Dispose
时检查WaitForItem
方法返回false,并且不会阻止等待。
代码类似于:
A a = new A(1);
a.Method();
bool finished = true;
Thread t1 = new Thread(() =>
{
finished = a.WaitForItem(Timeout.Infinite);
});
Thread t2 = new Thread(() =>
{
a.Dispose();
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
代码阻止永远等待项目(t1.Join()
)。我理解调用Close
,这也是处理对象的意思,不会影响句柄的状态,但是如何用false退出方法(捕获ObjectDisposedException
) ?
尽管不是在第二个线程上调用a.Dispose()
而是调用另一个方法来释放ManualResetEvent,但是对WaitOne()的调用被阻止了。
答案 0 :(得分:1)
仅在调用成员函数之前已经放置了对象时才会引发ObjectDisposedException
。在您的情况下不会发生这种情况,因为在mre.WaitOne(timeout)
之前调用函数mre.Dispose()
。
一旦简单修复就可以在具有较短超时值的循环中调用mre.WaitOne(timeout)
函数。例如一个人希望10 seconds
函数有WaitForItem
超时,然后只需1秒超时即可调用mre.WaitOne(timeout)
,并且会在10次尝试后放弃。
下面将解释WaitForItem
功能的典型实现。 WaitForItem
有3个可能的返回值。
1 =在mre
上触发设置
0 =在指定的超时内未触发设置
-1 =在超时之前处置对象。
public int WaitForItem(int timeout){
try{
int nReturnCode = 0;
int nTimeElapsed = 0;
while (true)
{
if (mre.WaitOne(1000)) //just wait for 1 second
{
nReturnCode = 1; //Set call on ManualResetEvent
break;
}
else //Timeout need to repeat
{
nTimeElapsed += 1000;
if (nTimeElapsed > timeout)
{
nReturnCode = 0; //timeout
break;
}
}
}
return nReturnCode;
}catch(ObjectDisposedException){
return -1; //Exception
}
}