我正在使用一个Autoresetevent,可以在事件(例外处理)上进行多个集呼叫。有时会调用额外的集合,因此,当代码在Waitone事件上进行第二个调用时,它就直接通过,因为门已经打开。

解决方案是在Waitone之前立即致电重置。是否有更干净的解决方案,或者这是唯一的方法?示例代码:

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可能被调用了多个例外(或Rethrown例外),因此Waitone只是流过。

我的解决方案是始终在Waitone之前致电重置。这是资助解决方案,设计差,还是有其他类型的事件可以处理这种情况?

编辑:我刚刚移动了事件旁边的评论重置(拟议的解决方案)。

有帮助吗?

解决方案

我担心的是,如果您在WaitOne()之前调用reset(),如果没有set()被调用,那么您会遇到麻烦。如果您调用Set(),则可能会发生这种情况,然后在击中Waitone()之前立即点击reset()。即使您两次调用set(),也不能保证您在两者之间都不会调用reset(),而不会释放任何机制。

理想情况下,您可以尝试.. catch..catch..finally block,并在最后块中调用set(),并且没有例外的处理。那对你有用吗?

汉斯是正确的,在这种情况下,多线程是不必要的。我的关注仅适用于您真正的多线程与WaitOne()的呼叫。

这也让我担心您正在调用不止一次的设置...这是否意味着当第一个套装被调用时,资源应该真正锁定?如果您仍然能够第二次点击Set(),对我来说,您仍在执行与共享资源一起使用的代码。在这种情况下,您不希望呼叫waitone()取消阻止。

另请注意,从MSDN:

不能保证对设定方法的每个调用都会释放线程。如果两个呼叫太近,以便在释放线程之前发生第二个呼叫,则仅释放一个线程。好像第二个电话没有发生。

无论如何,您的代码似乎应该去抛出异常的路线,或者跑步完成,但不能同时进行。即,您不应该两次调用Set()。

其他提示

这不是一个真正的问题,waitone()呼叫会自动重置事件。毕竟,您使用了Autoresetevent,而不是手动Resetevent。关键短语这里是自动重置。

看到它通过Waitone()呼叫向右蒸也很正常。您有一个不错的多重核心CPU,当您打电话给start()时,该线程立即开始启动,而仅需几微秒即可完成工作。毫秒,无论如何,比眼睛的眨眼更快。

也许更重要的是,您只是在这里不需要线程。开始一个,然后等待它完成是毫无意义的。只需直接调用剂量罩()即可。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top