Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 等待所有线程_C#_Multithreading - Fatal编程技术网

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);