【发布时间】:2016-10-13 23:27:04
【问题描述】:
我发现如果我使用实现,以下代码实际上不会等待任务 client.SendAsync():
taskList.Add(Task.Factory.StartNew(() => new Program().Foo()));
如果我将其从 Task.Factory.StartNew() 更改为 new Program().Foo() 或 Task.Run(() => new Program.Foo(),它将正确输出一些信息。两者有什么区别?
internal class Program
{
private async Task Foo()
{
while (true)
{
var client = new HttpClient();
var requestMessage = new HttpRequestMessage(HttpMethod.Head, "http://www.google.com");
HttpResponseMessage response = await client.SendAsync(requestMessage);
Console.WriteLine(response.RequestMessage.RequestUri.ToString());
}
}
private static void Main(string[] args)
{
var taskList = new List<Task>();
// This won't output anything.
taskList.Add(Task.Factory.StartNew(() => new Program().Foo()));
// This will.
taskList.Add(Task.Run(() => new Program().Foo()));
// So does this.
taskList.Add(new Program().Foo());
Task.WaitAll(taskList.ToArray());
}
}
基于this MSDN article,看来Task.Run(someAction);等价于Task.Factory.StartNew(someAction, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
但即使我将代码更改为此,它也不会输出任何内容。为什么?
internal class Program
{
private async Task Foo()
{
while (true)
{
var client = new HttpClient();
var requestMessage = new HttpRequestMessage(HttpMethod.Head, "http://www.google.com");
HttpResponseMessage response = await client.SendAsync(requestMessage);
Console.WriteLine(response.RequestMessage.RequestUri.ToString());
}
}
private static void Main(string[] args)
{
var taskList = new List<Task>();
taskList.Add(Task.Factory.StartNew(() => new Program().Foo(), CancellationToken.None,
TaskCreationOptions.DenyChildAttach, TaskScheduler.Default));
//taskList.Add(Task.Run(() => new Program().Foo()));
//taskList.Add(new Program().Foo());
Task.WaitAll(taskList.ToArray());
}
}
【问题讨论】:
-
主题行中问题的答案 - 不,除非您要求。
-
看看异步/等待模式。这将拓宽你在这个问题上的视野。
-
@derekhh:阅读your whole reference。您引用的部分以 When you pass an Action to Task.Run 为前缀,您的代码没有这样做。在博客文章的后面,他解释了
Task.Run与异步委托的行为有何不同。
标签: c# async-await task-parallel-library