如何讓前臺線程等待所有後臺(子)線程在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. 如何等待所有線程完成?
- 2. 如何讓UI線程等待後臺線程完成?
- 3. 試圖等待所有線程完成
- 4. 如何讓主線程等待所有子線程完成?
- 5. 等待所有子線程來完成(在C)
- 6. Perl:等待後臺進程完成
- 7. C#.NET等待所有線程完成並獲得返回值
- 8. 如何使主要等待所有線程完成
- 9. 如何使父線程等待子線程完成 - C#
- 10. SDL和C++:等待多線程完成
- 11. C#等待多個線程完成
- 12. 請等待後臺線程?
- 13. Java等待線程完成
- 14. 在循環中創建線程並等待所有線程完成/中止
- 15. Java多線程等待線程完成
- 16. 未來等待FixedThreadPool在所有線程完成之前返回
- 17. 等待Executor中的所有線程完成?
- 18. C#生成新線程,然後等待
- 19. 等待所有線程完成的有用模式是什麼?
- 20. 使主線程等待,直到所有其他Qthread完成
- 21. 並行計算多個值。等待所有線程完成
- 22. 我可以等待一個特定的後臺線程完成,然後另一個後臺線程啓動?
- 23. 有主線程等待一個線程完成任務(但沒有完成)
- 24. 如何等待onReceive在同一個線程中完成?
- 25. 如何等待一組線程'真的'在java中完成?
- 26. 如何等待產生的線程在python中完成?
- 27. Wscript make程序無法在後臺運行或等待完成
- 28. C#應用程序正在等待線程完成?
- 29. 等待所有線程完成一份工作,然後再做另一個
- 30. 如何等待SparkContext完成所有過程?
可能重複的工作然後等到所有完成](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