在ManualResetEvent或Thread.Sleep()之间做出选择

deo*_*oll 8 c# multithreading sleep manualresetevent

我不确定采用哪种策略......我专注于我的操作完成,但我也想将性能问题保持在最低限度......有一种名为Execute()的方法必须等待(同步运行)直到操作完成.此操作发生在另一个线程上.有两种方法可以实现同样的事情......

通过使用ManualResetEvent

void Execute()
{
    taskHandle = new ManualResetEvent(false);
    .
    .
    //delegate task to another thread
    .
    .
    taskHandle.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)

要么

通过使用简单的while构造

void Execute()
{
    .
    .
    //delegate task to another thread
    .
    .
    while (!JobCompleted)
        Thread.Sleep(1000);
}
Run Code Online (Sandbox Code Playgroud)

我应采用两种方法中的哪一种......为什么?

编辑:

Q2.如果我在构造时只是空了怎么办?有什么不同...?

while(!JobCompleted);
Run Code Online (Sandbox Code Playgroud)

编辑:(之前我收集过的东西)

http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml - 这篇文章说手动复制比较慢,因为它们离开了托管代码并重新进入......

Ada*_*son 13

出于好奇,为什么ManualResetEventAutoResetEvent呢?无论哪种方式,通过睡眠 - 检查 - 睡眠方法与OS原语一起使用.

你也可以使用一个Monitor锁(显式地通过Monitor.EnterMonitor.Exit,或通过一个lock块),但方法应该基于你实际做的事情; 如果它是"只有这些东西中的一个并且我需要独占访问" 的场景,那么使用Monitor锁定.如果它是"我需要等到另一个线程因资源访问以外的原因而完成 ",那么使用AutoResetEventManualResetEvent.

Thread.Join如果(并且仅当)使用的建议是好的

  1. 您可以访问其他Thread对象
  2. 另一个线程终止之前,您不希望执行.

如果其中任何一个不是真的(你没有访问权限,或者其他线程不会终止,它只会发出"全部清除"信号),那么Thread.Join就不可行了.

最糟糕的选择是

while(!JobCompleted);

因为这将使处理器与变量的不必要检查捆绑在一起,而不会在它们之间产生任何停顿.是的,它将阻止你的线程,直到操作完成,但你将最大化CPU使用率(或至少一个核心的价值).