首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有WaitOne方法可以先调用Reset?

是否有WaitOne方法可以先调用Reset?
EN

Stack Overflow用户
提问于 2010-11-06 03:37:25
回答 2查看 4.3K关注 0票数 2

我正在使用一个AutoResetEvent,其中可以对一个事件进行多个Set调用(异常处理)。有时会调用额外的Set,因此当代码对WaitOne事件进行第二次调用时,它只是直接通过,因为门已经打开。

解决方案是在WaitOne之前调用Reset。有没有更干净的解决方案,或者这是唯一的解决方案?示例代码:

代码语言:javascript
复制
private void DoSomeWork()
{
    Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
    thrd.Start();

    //mEvt.Reset();
    mEvt.WaitOne();

    //continue with other stuff
}

private void DoSomeOtherStuff()
{
    /* lots of stuff */

    mEvt.Set();
}

private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
   mEvt.Set();
}

在异常处理之后,我需要再次调用DoSomeWork,但是由于Set可能在多个异常(或重新抛出的异常)中被调用,所以WaitOne只是流过。

我的解决方案是总是在WaitOne之前调用Reset。这是合适的解决方案,糟糕的设计,还是有不同类型的事件来处理这种情况?

编辑:我只是将注释的重置(建议的解决方案)移到了事件旁边。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-06 05:02:12

我担心的是,如果在调用WaitOne()之前调用Reset(),如果没有调用任何Set(),那么就会遇到麻烦。如果您调用Set(),然后在调用WaitOne()之前立即单击Reset(),则可能会发生这种情况。即使你调用了Set()两次,也不能保证你不会在两次之后调用Reset(),阻塞线程而没有释放机制。

理想情况下,您应该有一个try..catch..finally块,并在finally块中调用Set(),而不是让异常处理跨方法传播。这对你有效吗?

Hans是正确的,在这种情况下,多线程是不必要的。我所关心的问题只有在您真正使用多线程调用WaitOne()时才适用。

我还担心你不止一次调用set ...这是否意味着当第一个集合被调用时,资源真的应该保持锁定状态?如果你仍然能够第二次点击Set(),对我来说,这说明你仍然在执行使用共享资源的代码。在这种情况下,您不希望对WaitOne()的调用解除阻塞。

另请注意,从MSDN:

不能保证每次调用Set方法都会释放一个线程。如果两个调用离得太近,导致第二个调用在线程释放之前发生,则只释放一个线程。就好像第二次调用没有发生一样。

在任何情况下,您的代码似乎应该要么抛出异常,要么运行到完成,但不能两者兼而有之。也就是说,你不应该两次调用Set()。

票数 2
EN

Stack Overflow用户

发布于 2010-11-06 04:50:37

这不是真正的问题,WaitOne()调用会自动重置事件。毕竟,您使用的是AutoResetEvent,而不是ManualResetEvent。这里的关键短语是自动重置。

看到它直接通过WaitOne()调用也是很正常的。你已经有了一个很好的多核CPU,当你调用Start()时,线程就立即启动了,并且只用了几微秒就完成了工作。毫秒,不管怎么说,比你眨眼的时间还快。

也许更重要的是,这里不需要线程。启动一个,然后等待它结束是没有意义的。只需直接调用DoSomeOtherStuff()即可。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4109395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档