Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 是否使用Task.WaitAll()处理等待的任务?_C#_Multithreading_Async Await - Fatal编程技术网

C# 是否使用Task.WaitAll()处理等待的任务?

C# 是否使用Task.WaitAll()处理等待的任务?,c#,multithreading,async-await,C#,Multithreading,Async Await,理想情况下,我想做的是使用非阻塞模式延迟任务,然后等待所有任务完成。我尝试添加task.Delay返回的task对象,然后使用task.WaitAll,但似乎没有帮助。我应该如何解决这个问题 class Program { public static async void Foo(int num) { Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId,

理想情况下,我想做的是使用非阻塞模式延迟任务,然后等待所有任务完成。我尝试添加task.Delay返回的task对象,然后使用task.WaitAll,但似乎没有帮助。我应该如何解决这个问题

class Program
{
    public static async void Foo(int num)
    {
        Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId, num);

        var newTask = Task.Delay(1000);
        TaskList.Add(newTask);
        await newTask;

        Console.WriteLine("Thread {0} - End {1}", Thread.CurrentThread.ManagedThreadId, num);
    }

    public static List<Task> TaskList = new List<Task>();

    public static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            int idx = i;
            TaskList.Add(Task.Factory.StartNew(() => Foo(idx)));
        }

        Task.WaitAll(TaskList.ToArray());
    }
}
类程序
{
公共静态异步void Foo(int num)
{
WriteLine(“线程{0}-Start{1}”,Thread.CurrentThread.ManagedThreadId,num);
var newTask=任务延迟(1000);
任务列表。添加(newTask);
等待新任务;
WriteLine(“线程{0}-End{1}”,Thread.CurrentThread.ManagedThreadId,num);
}
public static List TaskList=new List();
公共静态void Main(字符串[]args)
{
对于(int i=0;i<3;i++)
{
int-idx=i;
TaskList.Add(Task.Factory.StartNew(()=>Foo(idx));
}
Task.WaitAll(TaskList.ToArray());
}
}

这就是您想要实现的目标吗

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    class Program
    {
        public static async Task Foo(int num)
        {
            Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId, num);

            await Task.Delay(1000);

            Console.WriteLine("Thread {0} - End {1}", Thread.CurrentThread.ManagedThreadId, num);
        }

        public static List<Task> TaskList = new List<Task>();

        public static void Main(string[] args)
        {
            for (int i = 0; i < 3; i++)
            {
                int idx = i;
                TaskList.Add(Foo(idx));
            }

            Task.WaitAll(TaskList.ToArray());
            Console.WriteLine("Press Enter to exit...");
            Console.ReadLine();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统线程;
使用System.Threading.Tasks;
命名空间控制台应用程序
{
班级计划
{
公共静态异步任务Foo(int num)
{
WriteLine(“线程{0}-Start{1}”,Thread.CurrentThread.ManagedThreadId,num);
等待任务。延迟(1000);
WriteLine(“线程{0}-End{1}”,Thread.CurrentThread.ManagedThreadId,num);
}
public static List TaskList=new List();
公共静态void Main(字符串[]args)
{
对于(int i=0;i<3;i++)
{
int-idx=i;
添加(Foo(idx));
}
Task.WaitAll(TaskList.ToArray());
Console.WriteLine(“按Enter键退出…”);
Console.ReadLine();
}
}
}
输出:

Thread 10 - Start 0 Thread 10 - Start 1 Thread 10 - Start 2 Thread 6 - End 0 Thread 6 - End 2 Thread 6 - End 1 Press Enter to exit... 线程10-开始0 线程10-开始1 线程10-开始2 螺纹6-端部0 螺纹6-端部2 螺纹6-端部1 按回车键退出。。。
需要注意的是,因为Foo是异步的,所以它本身就是一个任务。您的示例中的任务只是启动
Foo
任务,但不要等待它

换句话说,
Task.WaitAll(TaskList.ToArray())
只是等待每个
Task.Delay
开始,但它不是等待所有这些任务完成

这可能是您正试图实现的目标:

class Program
{
    public static async Task Foo(int num)
    {
        Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId, num);

        var newTask = Task.Delay(1000);

        await newTask;
        Console.WriteLine("Thread {0} - End {1}", Thread.CurrentThread.ManagedThreadId, num);

    }

    public static List<Task> TaskList = new List<Task>();

    public static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            int idx = i;

            Task fooWrappedInTask = Task.Run(() => Foo(idx));
            TaskList.Add(fooWrappedInTask);
        }

        Task.WaitAll(TaskList.ToArray());
        Console.WriteLine("Finished waiting for all of the tasks: - Thread {0}", Thread.CurrentThread.ManagedThreadId);
    }
}
类程序
{
公共静态异步任务Foo(int num)
{
WriteLine(“线程{0}-Start{1}”,Thread.CurrentThread.ManagedThreadId,num);
var newTask=任务延迟(1000);
等待新任务;
WriteLine(“线程{0}-End{1}”,Thread.CurrentThread.ManagedThreadId,num);
}
public static List TaskList=new List();
公共静态void Main(字符串[]args)
{
对于(int i=0;i<3;i++)
{
int-idx=i;
Task fooWrappedInTask=Task.Run(()=>Foo(idx));
TaskList.Add(fooWrappedInTask);
}
Task.WaitAll(TaskList.ToArray());
WriteLine(“已完成等待所有任务:-线程{0}”,Thread.CurrentThread.ManagedThreadId);
}
}
我已经对此进行了测试,它生成了您想要的控制台输出


这里的主要区别是我们调用的是
Task.Run
,而不是
Task.Factory.StartNew

您可能有一个
任务
,它返回一个
任务
,甚至可能返回另一个
任务
。你会认为这是一个任务“链”

Task.Run
返回表示链中最后一个任务的
Task
。当您等待它时,您正在等待任务链中的每个环节完成


相比之下,
Task.Factory.StartNew
返回表示链中第一个链接的任务。在你等待了它之后,剩下的链条就等着你了。如果
任务
返回的内容不是另一个
任务

那么这很好,为什么要在控制台应用程序中执行此操作?没有上下文(默认情况下),因此
await
总是表现得很奇怪……您希望在控制台中看到什么?这与你所看到的有什么不同?@AndrewShepherd:我希望看到的是六行,分别显示每个任务的开始和结束。但现在我看到的只是开始…你的代码似乎对我有用。。。(在wpf解决方案中运行,但代码在GUI线程上运行后仍然有效…
async void
传递给
Task.Factory.StartNew
的方法是个坏主意。您无法跟踪它启动的挂起任务,也无法捕获它在
wait
之后可能引发的任何异常。查看此以了解更多信息:不是真的。这将只输出前三行“开始…”,而不会输出“结束…”。这意味着这些任务还没有真正完成(我知道会创建新的任务对象,而不是添加到任务列表中的原始任务对象)。所以我真的很想找到一种方法,能够正确地表现,并表明这三项任务已经完成。@Derekh,你试过了吗?我已经发布了一个完整的例子。您可以看到Start/Start/Start,因为您可以并行启动任务。每个任务都有匹配的结束。还是想一个接一个的开始呢?谢谢!我刚刚注意到,您还将Foo的返回类型从void更改为Task。是的,将此内容更改回原来的内容将看到与您所写内容完全相同的行为。:)@derekhh,是的,请看我对您关于
async void
的问题的评论。另外,请务必阅读有关嵌套任务的内容,这是非常有用的。您可以在此处创建嵌套任务,这将
任务。在我看来,运行
会自动展开,这是不必要的。否则,代码似乎与。不确定这是OP想要的。