Task.Factory.StartNew是否等待任务完成?

德雷赫

我发现以下代码实际上不会等待任务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());
    }
}

根据此MSDN文章,似乎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());
    }
}
尤瓦尔·伊茨恰科夫(Yuval Itzchakov)

问题出在Task.Factory.StartNew不是“任务感知”的事实意思是,方法调用的返回类型StartNew实际上是Task<Task>这意味着您仅在等待外部任务完成,而不是内部任务

一个简单的解决方案是使用TaskExtensions.Unwrap()方法:

private static void Main(string[] args)
{
    var taskList = new List<Task>();
    taskList.Add(Task.Factory.StartNew(() => new Program().Foo()).Unwrap());

    Task.WaitAll(taskList.ToArray());
}

Task.Run确实有效,因为它是“任务感知”的。它有一个重载,接受一个Func<Task>内部调用Unwrap,仅返回内部任务。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

任务计划程序:在Task.Factory.StartNew中等待时,线程是否返回到池中?

检查Task.Factory.StartNew何时完成?

Task.Factory.StartNew方法是否可能永远无法完成执行?

Task.Factory.StartNew与新Task

使用Task Factory存储每个任务的任务完成时间

Parallel.ForEach与Task.Factory.StartNew

循环使用Task.Factory.StartNew

关于Task.Start(),Task.Run()和Task.Factory.StartNew()的使用

如何处理Task.Factory.StartNew异常?

使用Task.Factory.StartNew()然后返回值

UWP 中 System.Threading.Tasks.Task.Factory.StartNew() 的问题?

没有ui freez的Task.Factory.StartNew延迟

Web Api C#-Task.Factory.startnew与异步

什么是合格的CancellationToken到Task.Factory.StartNew的目的()

为 Task.Factory.StartNew() 传递迭代器的常量副本

Task.Factory.StartNew <T>和Task <T> .Factory.StartNew之间有什么区别吗?

Task.WaitAll不等待任务完成

Task.WhenAll 不等待任务完成

Task.Run和Task.Factory.StartNew有什么区别

为什么Task.Factory.StartNew立即返回而Task.Run没有返回?

带有异步lambda和Task.WaitAll的Task.Factory.StartNew

Task.Run与Task.Factory.StartNew-预期的死锁未发生

vb.net Task.Factory 需要多个任务吗?

使用 Task.Factory.FromAsync 创建基于 I/O 的任务

Task.ContinueWith()父任务不等待子任务完成

Task.Factory.StartNew() 的第二个参数有什么用?

在Subscribe中调用Task.Factory.StartNew(async()=> {})通常是可疑的吗?

Task.Factory.StartNew和new Thread()。Start()有什么区别?

Moq方法,由System.Threading.Tasks.Task.Factory.StartNew调用