C# 在另一个线程上处理ManualReset事件
与之类似,我有一个带有私有ManualReset事件的类:C# 在另一个线程上处理ManualReset事件,c#,multithreading,C#,Multithreading,与之类似,我有一个带有私有ManualReset事件的类: class A { private ManualResetEvent mre = new ManualResetEvent(true); private void Method(){ //do something mre.Reset(); } public bool WaitForItem(int timeout){
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
时,如何检查方法是否返回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()的调用被阻止。只有在调用成员函数之前已处理对象时,才会引发ObjectDisposedException
。这在您的情况下不会发生,因为函数mre.WaitOne(timeout)
在mre.Dispose()之前调用
一个简单的修复方法是在一个具有较短超时值的循环中调用mre.WaitOne(timeout)
函数。e、 g.如果想让WaitForItem
函数有10秒
超时,那么mre.WaitOne(timeout)
只需1秒超时即可调用,并在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
}
}您遇到这个问题表明您的应用程序设计中存在可疑之处。但如果确实需要这样做,请尝试使用ManualResetEventSlim
并使用该方法。在处理MRE之前,只需更改Dispose
方法以设置取消令牌。不过,老实说,你需要重新思考你的设计。这样的事情真的不必要。