c# - 如何正确创建可等待的方法

标签 c# async-await

我正在编写一些可等待的方法,并且我在互联网上找到了很多这样做的方法。所以我来这里是为了了解每条路到底发生了什么,以及是否必须取消某些路。

据我所知,有两种可等待的方法:

那些调用其他可等待方法的:

public async Task<Foo> GetFooAsync()
{
    var foo = await TrulyGetFooAsync();

    // Do stuff with foo

    return foo;
}

我没有找到任何其他方法来做到这一点,我认为这是正确的方法。如果我错了告诉我!

那些只调用非等待方法的:

我想到了这些问题。

例如,我看到了这个:

例1

public async Task<Foo> GetFooAsync()
{
    return await Task.Run(() => TrulyGetFoo());
}

据我所知,async/await 关键字是无用的,可以避免给出这个:

例2

public Task<Foo> GetFooAsync()
{
    return Task.Run(() => TrulyGetFoo());
}

最后一个例子是我到目前为止所做的。关于这一点,两者之间有区别吗:

Task.Run(() => TrulyGetFoo());

Task.Run((Foo)TrulyGetFoo); // I don't know if the cast is required at any time but in my code, it was

???

但是我最近发现是这样的:

例3

public Task<Foo> GetFooAsync()
{
    TaskCompletionSource<Foo> tcs = new TaskCompletionSource<Foo>();
    tcs.SetResult(TrulyGetFoo());
    return tcs.Task;
}

如果我理解正确,可等待的方法并不总是在另一个线程上运行???我的猜测是第三个示例提供了这种机制(但如何???我只在第三个示例中看到同步代码),而示例 1 和 2 将始终在工作线程上运行???

可能还有其他方法可以编写可等待的方法,让我知道吧。

最佳答案

For example, I saw [Task.Run wrappers around synchronous code]

This is a bad practice .我有一篇博文解释了 why Task.Run should not be used as a method implementation .

As far as I understand, the async/await keywords are useless and can be avoided

是的,但是 I don't recommend eliding async / await in more complex methods .

I recently found [TaskCompletionSource<T>]

如评论中所述,您的代码示例仍然是同步的。

要使其异步,您的代码应该开始一些操作并返回 TaskCompletionSource<T>.Task .然后,每当该操作完成时,您的完成处理程序应调用 TaskCompletionSource<T>.SetResult (或类似的方法)。有关示例,请参阅 TAP wrappers for EAPTAP wrappers for WaitHandle s .

TaskFactory.FromAsync也是 TaskCompletionSource<T> 的包装器, 并用于 TAP wrappers for APM .

关于c# - 如何正确创建可等待的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43393169/

相关文章:

c# - Unity 广告没有自动初始化?

c# - 为什么这行得通?方法重载+方法覆盖+多态

c# - sql server 中 System.Version 的数据类型

c# - 如何在 C# 中将 Array 转换为 List<object>?

快速调用没有返回值的异步函数

javascript - 当它无法识别时,我如何使用等待?

c# - 一律取消task.delay还是用exception来控流?

c# - 如何使用 Google.Apis.Drive.V3 断开(删除访问)谷歌驱动器?

async-await - 这是等待异步内容的正确用法吗?

c# - 从头开始异步处理