如何让前台线程等待所有后台(子)线程在C#中完成?我需要从队列(数据库)中获取待处理作业的列表,启动一个新线程来执行它们中的每一个,并最终等待所有子线程完成。如何在C#中做到这一点?提前致谢。如何等待所有后台线程完成(在C#中)?
回答
考虑使用线程池。你想要的大部分已经完成了。有一个example from Microsoft它几乎完成你的整个任务。将“fibonacci”替换为“数据库任务”,听起来像是你的问题。
我几分钟前就读过这篇文章,并即将回复说这是我正在寻找的解决方案。谢谢回复。 – RKP 2010-10-13 15:06:50
您可以将每个启动的线程存储在一个数组中。然后当你需要等待它们全部时,在循环中的数组中的每个线程上调用Join方法。
Thread child = new Thread(...);
Threads.Add(child);
child.Start()
...
foreach(Thread t in Threads)
{
t.Join();
}
HTH
感谢您的答复。我认为thread.Join方法适用于单线程或非常少的固定线程数。对于多线程,我认为有一个WaitAll方法,但我找不到一个好的代码示例。 – RKP 2010-10-13 13:37:54
@RKP:等待所有线程完成和等待它们一样,不是吗?有一个winapi函数WaitForMultipleObjects,但它不是C#,尽管你可以使用它,但我没有看到任何意义。 – 2010-10-13 13:40:25
这是不完整的代码,但ManualResetEvent
为你的作品
var waitEvents = new List<ManualResetEvent>();
foreach (var action in actions)
{
var evt = new ManualResetEvent(false);
waitEvents.Add(evt);
ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, TimeoutCallback, state, 5000, true);
}
if (waitEvents.Count > 0)
WaitHandle.WaitAll(waitEvents.ToArray());
创建一个结构,让您的工作线程的跟踪
private struct WorkerThreadElement
{
public IAsyncResult WorkerThreadResult;
public AsyncActionExecution WorkerThread;
}
您还需要跟踪预期要创建的线程总数以及当前有多少个线程完成
private int _TotalThreads = 0;
private int _ThreadsHandled = 0;
private List<WorkerThreadElement> _WorkerThreadElements = new List<WorkerThreadElement>();
然后创建一个自动复位句柄以等待线程完成。
// The wait handle thread construct to signal the completion of this process
private EventWaitHandle _CompletedHandle = new AutoResetEvent(false);
你还需要一个委托创建新主题 - 这样做有多种方式,但我选择了一个简单的委托为这个例子的目的
// Delegate to asynchronously invoke an action
private delegate void AsyncActionExecution();
让asume的Invoke方法是创建所有线程并等待其执行的入口点。所以我们有:
public void Invoke()
{
_TotalThreads = N; /* Change with the total number of threads expected */
foreach (Object o in objects)
{
this.InvokeOneThread();
}
// Wait until execution has been completed
_CompletedHandle.WaitOne();
// Collect any exceptions thrown and bubble them up
foreach (WorkerThreadElement workerThreadElement in _WorkerThreadElements)
{
workerThreadElement.WorkerThread.EndInvoke(workerThreadElement.WorkerThreadResult);
}
}
InvokeOneThread是用于为一个操作创建单个线程的方法。这里我们需要创建一个工作线程元素并调用实际的线程。从线程完成
private void InvokeOneThread()
{
WorkerThreadElement threadElement = new WorkerThreadElement();
threadElement.WorkerThread = new AsyncActionExecution();
threadElement.WorkerThreadResult = threadElement.WorkerThread.BeginInvoke(actionParameters, InvokationCompleted, null);
_WorkerThreadElements.Add(threadElement);
}
回调
private object _RowLocker = new object();
/// <summary>
/// Increment the number of rows that have been fully processed
/// </summary>
/// <param name="ar"></param>
private void InvokationCompleted(IAsyncResult ar)
{
lock (_RowLocker)
{
_RowsHandled++;
}
if (_TotalThreads == _ThreadsHandled)
_CompletedHandle.Set();
}
完成
使用动态数据,你可以通过你的对象和WaitHandle的(ActionResetEvent),让你等待所有的后台线程完成不宣而一个额外的类:[C#产生多个线程的
static void Main(string[] args)
{
List<AutoResetEvent> areList = new List<AutoResetEvent>();
foreach (MyObject o in ListOfMyObjects)
{
AutoResetEvent are = new AutoResetEvent(false);
areList.Add(are);
ThreadPool.QueueUserWorkItem(DoWork, new { o, are });
};
Console.WriteLine("Time: {0}", DateTime.Now);
WaitHandle.WaitAll(areList.ToArray());
Console.WriteLine("Time: {0}", DateTime.Now);
Console.ReadKey();
}
static void DoWork(object state)
{
dynamic o = state;
MyObject myObject = (MyObject)o.o;
AutoResetEvent are = (AutoResetEvent)o.are;
myObject.Execute();
are.Set();
}
- 1. C#等待所有线程完成Main()
- 2. C++等待所有线程完成
- 3. 如何等待所有线程完成
- 4. 如何等待所有线程完成?
- 5. 如何让UI线程等待后台线程完成?
- 6. 试图等待所有线程完成
- 7. 如何让主线程等待所有子线程完成?
- 8. 等待所有子线程来完成(在C)
- 9. Perl:等待后台进程完成
- 10. 为什么在后台线程不会等待任务完成?
- 11. UI线程如何等待直到后台线程完成处理?
- 12. C#.NET等待所有线程完成并获得返回值
- 13. 如何让我的方法等待所有线程完成?
- 14. 如何使主要等待所有线程完成
- 15. 如何等待线程在C#中完成执行?
- 16. 如何使父线程等待子线程完成 - C#
- 17. SDL和C++:等待多线程完成
- 18. C#等待多个线程完成
- 19. 等待UI线程完成
- 20. 等待线程完成python
- 21. Java等待线程完成
- 22. 如何等待一个线程完成
- 23. AJAX线程 - 如何等待它完成?
- 24. 请等待后台线程?
- 25. 如何让EDT等待后台线程?
- 26. 如何等待所有NSOperations完成?
- 27. 等待所有$ http.get完成
- 28. 等待C++中的所有线程
- 29. 在循环中创建线程并等待所有线程完成/中止
- 30. 如何等待CreateProcessAsUser在C#中完成
可能重复的工作然后等到所有完成](http://stackoverflow.com/questions/2528907/c-spawn-multiple-threads-for-work-then-wait-until-all-finished) – 2010-10-13 13:25:33
感谢所有的快速答复我的问题 – RKP 2010-10-13 15:14:13
你尝试[EventWaitHandle();](http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx) – Bonshington 2010-10-13 13:47:13