等待后台线程完成

Ben*_*jol 5 c# background-process

很抱歉,如果这是重复的,但我不太确定我需要使用哪些术语来查找此问题的现有答案.

我正在尝试提高应用程序的启动性能,伪代码看起来有点像这样.

LoadBigFileFromDisk();  //slow
SetupNetwork();         //even slower
UseBigFileFromDisk();
Run Code Online (Sandbox Code Playgroud)

我认为第一步是磁盘绑定,另一个是网络绑定(并且速度较慢),我可以在后台线程中运行第一步(当前正在玩ThreadPool.QueueUserWorkItem,但不确定这是否是最好的方式)并提高性能一点点.

它有效,但令我担心的是,我依靠的第二步足够慢,第一步完成.

我知道我可以在_done某个地方设置一个布尔值while !,但是有更优雅/惯用的解决方案吗?

(不是.Net 4.0,所以虽然我对基于任务的感兴趣,但我需要后备解决方案).

xan*_*tos 3

在“主类”中执行以下操作:

ManualResetEvent mre = new ManualResetEvent(false);
Run Code Online (Sandbox Code Playgroud)

在你的“main”方法中执行以下操作:

// Launch the tasks

mre.WaitOne();
Run Code Online (Sandbox Code Playgroud)

在任务完成时(就在返回之前:-))

mre.Set();
Run Code Online (Sandbox Code Playgroud)

如果您必须等待多个事件,请在“主”中创建多个事件ManualResetEvent并将它们放入一个数组中,每个事件“连接”到其中一个任务,然后每个任务Set在完成时获取其事件。然后在你的“main”中你做:

WaitHandle.WaitAll(arrayOfManualResetEvents);
Run Code Online (Sandbox Code Playgroud)

请注意,通过这种方式您最多可以等待 64 个事件。如果您需要更多,还有另一种方法(请注意,即使您位于 STA 线程(例如 WinForm 应用程序的主线程)上,也必须使用最后一个方法)。

ManualResetEvent mre = new ManualResetEvent(false);
int remaining = xxx; // Number of "tasks" that must be executed.

// Launch tasks

mre.WaitOne();
Run Code Online (Sandbox Code Playgroud)

在每个任务结束时

if (Interlocked.Decrement(ref remaining) == 0)
{
    mre.Set();
}
Run Code Online (Sandbox Code Playgroud)

只有最后一个任务才会将剩余字段递减为 0 和mre.Set()