【问题标题】:WaitHandle.WaitAll and ManualResetEvent.Set() - what should be first?WaitHandle.WaitAll 和 ManualResetEvent.Set() - 首先应该是什么?
【发布时间】:2013-01-23 02:45:22
【问题描述】:

我对 WaitHandle.WaitAll 的工作有疑问,希望能提供任何帮助。

假设我有这样的情况:父线程正在打开几个子线程,并且必须等待“做其他事情”,直到子线程完成它们的工作。

我使用 WaitHandle.WaitAll 并希望继续使用此方法。 (NO Thread.Join 等,请 :))

ManualResetEvent[] events = new ManualResetEvent[list.Count];

foreach (string row in list)
{
    events[i] = new ManualResetEvent(false);                

    Thread thread = new Thread(new ParameterizedThreadStart(DoSomething));
    thread.Start(events[i]); // start child thread

    System.Threading.Thread.Sleep(1000000);

    i++;
}

WaitHandle.WaitAll(events); // wait for child threads finish their work
...
...


private DoSomething(object sth)
{
// some stuff that executes only 1 second
ManualResetEvent.Set()
}

所以第一个新启动的子线程的情况是 ManualResetEvent.Set() 的调用在父线程中调用 WaitHandle.WaitAll(events) 之前。因为打开新子线程的循环有很长的超时时间。

所以我的问题是,这样的时间线不是问题吗? 在调用 ManualResetEvent.Set() 之前不应该调用 WaitHandle.WaitAll 吗?

【问题讨论】:

  • 不要使用ManualResetEvents和Threads,听起来如果你使用Tasks和Task.WaitAll()会更好。

标签: c# .net multithreading


【解决方案1】:

没关系。当所有事件都发出信号(设置)时,等待返回 - 无论是在调用等待之前还是之后发生。

【讨论】:

    【解决方案2】:

    正如人们所说,没关系,但是,您应该考虑使用 Task 类来处理这类事情。

    它还允许您同时或依次运行您的任务。

    那么你的代码就只有这个了:

    Task.WaitAll(
        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
        }),
        Task.Factory.StartNew(() => { Thread.Sleep(1000); }),
        Task.Factory.StartNew(() => { Thread.Sleep(1000); })
        );
    

    【讨论】:

    • svick 和 AgentFire,感谢您的建议。您的建议是否有一些性能优势?在哪些 Tasks 比 Threads 更好?我不知道这是否重要,但我的子线程做了一些“硬、长时间的 CPU 和数据库工作”,而父线程只创建它们,不能走得更远。
    • 我很惭愧地承认......但使用 Parallel 比记住如何使用 MRE 和 WaitHandles 容易得多。
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-15
    • 1970-01-01
    相关资源
    最近更新 更多