C# 等待所有线程
我对这段代码中的线程有点小问题 我只想一起运行很多任务,并在所有任务完成后继续C# 等待所有线程,c#,multithreading,C#,Multithreading,我对这段代码中的线程有点小问题 我只想一起运行很多任务,并在所有任务完成后继续 while (true) { // Run tasks together: foreach (object T in objectsList) { if (T.something>0) var task = Task.Factory.StartNew(() => T.RunObject()); task.Conti
while (true)
{
// Run tasks together:
foreach (object T in objectsList)
{
if (T.something>0)
var task = Task.Factory.StartNew(() => T.RunObject());
task.ContinueWith(delegate { ChangeObject(T, 1); }, TaskContinuationOptions.NotOnFaulted);
}
// <-- Here I want to wait for all the task to be finish.
// I know its task.Wait() but how to waitAll()?
System.Threading.Thread.Sleep(this.GetNextTime());
var RefreshObjects = new Task(loadObjectsList); RefreshObjects .Start(); RefreshObjects.Wait();
}
因为当objectsList[T]时,Tasks
将包含空值0
谢谢你的建议 如果
objectsList
实现IEnumerable(就像数组一样),
(并且列表中的对象少于64个),您可以使用:
public delegate void SyncDelegatesInParallelDelegate<in T>(T item);
public static class ParallelLinqExtensions
{
public static void SyncDelegatesInParallel<T>(
this IEnumerable<T> list,
SyncDelegatesInParallelDelegate<T> action)
{
var foundCriticalException = false;
Exception exception = null;
var waitHndls = new List<WaitHandle>();
foreach (var item in list)
{
// Temp copy of session for modified closure
var localItem = item;
var txEvnt = new ManualResetEvent(false);
// Temp copy of session for closure
ThreadPool.QueueUserWorkItem(
depTx =>
{
try { if (!foundCriticalException) action(localItem); }
catch (Exception gX)
{ exception = gX; foundCriticalException = true; }
finally { txEvnt.Set(); }
}, null);
waitHndls.Add(txEvnt);
}
if (waitHndls.Count > 0) WaitHandle.WaitAll(waitHndls.ToArray());
if (exception != null) throw exception;
}
}
只需切换条件并仅为符合条件的对象创建任务列表
var tasks = objectsList
.Where(x => x.Something() > 0)
.Select(x => {
var task = Task.Factory.StartNew(() => x.RunObject());
task.ContinueWith(t => ChangeObject(....));
return task;
})
.ToArray();
Task.WaitAll(tasks);
您的代码示例只需等待RunObject()
完成!如果需要,请跳过我的其余答案。如果您想等待继续完成,也可以使用
var tasks = objectsList
.Where(x => x.Something() > 0)
.Select(x => Task.Factory.StartNew(() => x.RunObject()).ContinueWith(t => ChangeObject(....)))
.ToArray();
Task.WaitAll(tasks);
因为
ContinueWith
会生成一个新任务。通过调用任务上的ContinueWith
而不将其分配给变量,可以轻松避免将select
作为语句委托。。如果他想等待续集完成,他也可以。如果他只是想完成最初的任务,他就必须遵守声明。真的很有帮助!谢谢。如果objectsList中的对象超过64个,这将不起作用,因为这是对等待句柄数量的限制。
var tasks = objectsList
.Where(x => x.Something() > 0)
.Select(x => {
var task = Task.Factory.StartNew(() => x.RunObject());
task.ContinueWith(t => ChangeObject(....));
return task;
})
.ToArray();
Task.WaitAll(tasks);
var tasks = objectsList
.Where(x => x.Something() > 0)
.Select(x => Task.Factory.StartNew(() => x.RunObject()).ContinueWith(t => ChangeObject(....)))
.ToArray();
Task.WaitAll(tasks);