等待后台线程完成

时间:2011-10-24 11:16:34

标签: c# background-process

很抱歉,如果这是重复的,但我不太清楚我需要使用哪些条款来查找此问题的现有答案。

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

LoadBigFileFromDisk();  //slow
SetupNetwork();         //even slower
UseBigFileFromDisk();

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

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

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

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

3 个答案:

答案 0 :(得分:3)

你可以尝试:

var loadTask=Task.Factory.StartNew(()=>LoadBigFileFromDisk());
var setupTask=Task.Factory.StartNew(()=>SetupNetwork());

Task.WaitAll(loadTask,setupTask);

UseBigFileFromDisk();

这使用任务并行库。

或:

var loadThread=new Thread(()=>LoadBigFileFromDisk());
var setupThread=new Thread(()=>SetupNetwork());

loadThread.Start();
setupThread.Start();

loadThread.Join();
setupThread.Join();

UseBigFileFromDisk();

当你不使用.NET 4.如果这些任务需要很长时间才能运行,那么最好避免使用线程池,因为它主要用于短期任务。

答案 1 :(得分:3)

在“主要班级”中这样做:

ManualResetEvent mre = new ManualResetEvent(false);

在你的“主要”方法中这样做:

// Launch the tasks

mre.WaitOne();

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

mre.Set();

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

Set

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

WaitHandle.WaitAll(arrayOfManualResetEvents);

每项任务结束时

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

// Launch tasks

mre.WaitOne();

只有最后一个任务会将剩余字段减少为0和if (Interlocked.Decrement(ref remaining) == 0) { mre.Set(); }

答案 2 :(得分:0)

尝试Thread.Join。像networkThread.Join()

这样的东西

http://msdn.microsoft.com/en-us/library/95hbf2ta.aspx