是否真的等待Task.Run()

时间:2017-05-20 18:10:36

标签: c#

我仍然在努力完全理解异步/等待方法。任何人都可以告诉我,因为主题确实等待Task.Run落后吗?有时人们做异步metod包括等待,但有时看到人们没有异步方法做Task.Run。什么是正确的方法?

4 个答案:

答案 0 :(得分:1)

不,async await只是为了允许代码在其他东西阻塞的情况下运行,而且它不会执行Task.Run,​​也不会启动新的线程。

https://blog.stephencleary.com/2013/11/there-is-no-thread.html是一个不错的解释。

答案 1 :(得分:0)

glGetError运算符只是在方法中启用async运算符。 await运算符将处理 awaitable 的任何内容。在.NET中,awaitTask awaitable 的一些示例。

Task<T>返回Task.RunTask返回Task.Run<T>,正如我所说,它们都是等待的,所以你可以Task<T>

如果您愿意,您甚至可以编写自己的等待类型:您只需确保满足等待的要求。 等待需要为await提供实施,以及它的实现。这是等待 example

GetAwaiter

现在你可以这样做:

public struct SimpleInt32Awaitable 
{ 
    public SimpleInt32Awaiter GetAwaiter() 
    { 
        return new SimpleInt32Awaiter(); 
    } 
}

public struct SimpleInt32Awaiter 
{ 
    public bool IsCompleted { get { return true; } }

    public void OnCompleted(Action continuation) 
    { 
    }

    public int GetResult() 
    { 
        return 5; 
    } 
}

答案 2 :(得分:0)

  

确实在等待Task.Run吗?

其他人已经与Cleary关于C#concurrency,There Is No Thread的许多优秀博客文章相关联。

不,它不会在幕后使用Task.Run

await不仅仅适用于Task.Run。它是在 完成后运行代码的。这可能是使用Task.Run创建的计算任务,但也可以是数据检索,例如使用ReadLineAsyncTask是用于模拟所有这些事物的类。

Task.Runused,用于排队在线程池上运行的工作。这在编写CPU绑定代码时是合适的,但是you shouldn't use Task.Run when dealing with IO-bound operations。在这种情况下,您的异步代码(可能使用async / await)应该使用异步IO方法,例如WriteLineAsync和前面提到的ReadLineAsync

使用Task.Run在工作线程上运行阻止代码是一种反模式。你永远不想这样做,即使它确实解锁你的GUI线程。

  

有时人们做异步metod包括等待,但有时看到人们在没有异步方法的情况下执行Task.Run。什么是正确的方法?

您确实可以使用Task创建Task.Run并让它运行,而不使用awaitContinueWith。这些被称为“火与忘记”。任务。他们很少是一个好主意。与使用await时不同,该任务抛出的任何异常都将丢失。

这可以通过 - 你猜对了 - 斯蒂芬•克利里,this StackOverflow answer.

来解释

答案 3 :(得分:-1)

在某些情况下,您被限制使用async和await - 这通常是您有时会看到使用Task.Run的原因 - 这允许您在同步方法中使用异步代码。

这是必要的一个示例,当使用带有子操作的MVC时 - 框架不支持异步子操作,因此您必须使用Task.Run调用异步代码。