4

在不执行await任务的情况下调用这样的方法时,我们可以返回以下内容:

public Task<bool> GetBoolAsync()
{
    return Task.FromResult(true);
}

什么是等效的 aIAsyncEnumerable<>并避免警告。

async IAsyncEnumerable<bool> GetBoolsAsync() // <- Ugly warning
{
    yield return true;
    yield break;
}

警告 CS1998 此异步方法缺少“等待”运算符,将同步运行。考虑使用 'await' 运算符来等待非阻塞 API 调用,或使用 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作。

4

2 回答 2

2

我可能会编写一个同步迭代器方法,然后ToAsyncEnumerableSystem.Linq.Async包中使用将其转换为异步版本。这是一个完整的例子:

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

class Program
{
    static async Task Main(string[] args)
    {
        await foreach (bool x in GetBoolsAsync())
        {
            Console.WriteLine(x);
        }
    }

    // Method to return an IAsyncEnumerable<T>. It doesn't
    // need the async modifier.
    static IAsyncEnumerable<bool> GetBoolsAsync() =>
        GetBools().ToAsyncEnumerable();

    // Regular synchronous iterator method.
    static IEnumerable<bool> GetBools()
    {
        yield return true;
        yield break;
    }
}

这符合接口(使用IAsyncEnumerable<T>),但允许同步实现,没有警告。请注意,async修饰符本身不是方法签名的一部分——它是一个实现细节。因此,在接口中指定为返回 a 的方法Task<T>IAsyncEnumerable<T>或者可以使用异步方法实现的任何方法,但不必如此。

当然,对于一个只想返回单个元素的简单示例,您可以ToAsyncEnumerable在数组或Enumerable.Repeat. 例如:

static IAsyncEnumerable<bool> GetBoolsAsync() =>
    new[] { true }.ToAsyncEnumerable();
于 2020-01-14T07:22:09.027 回答
1

我想你正在寻找TaskCompletionSource. 这为您提供了最大的灵活性。您可以在任务上设置例外,将其标记为未完成等。或者Task.FromResult

在许多情况下,启用 Task 来表示外部异步操作很有用。为此目的提供了 TaskCompletionSource。它可以创建可以分发给消费者的任务。消费者可以像在任何其他场景中处理任务成员变量一样使用任务成员。

考虑以下两个选项,我包括第一个,但你不能返回 a Task.CompletedTask<T>,但如果你只想返回一个已完成的任务,例如因为你可能out已经设置了一些参数,那么这可能就是你的答案。

    static async Task SomeMethod()
    {
        await Task.CompletedTask;
    }

或者 - 因为我们不能在没有 async 的情况下使用 await

    static Task<bool> SomeOtherMethod()
    {
        var taskSource = new TaskCompletionSource<bool>();
        taskSource.SetResult(true);
        return taskSource.Task;
    }

或(.Net 4.5+)

   static Task<bool> SomeEvenOtherMethod()
    {
        return Task.FromResult(true);
    }

或上述的异步变体

    static async Task<bool> SomeEvenOtherMethod()
    {
        var taskSource = new TaskCompletionSource<bool>();
        taskSource.SetResult(true);
        return (await taskSource.Task);
    }

或者:(.Net 4.5+)

    static async Task<bool> SomeEvenOtherMethod()
    {
        return(await Task.FromResult(true));
    }

并使用 IAsyncEnumerable

    static async IAsyncEnumerable<bool> GetBoolsAsync()
    {
        var t = await SomeOtherMethod();
        yield return t;
    }

或(.Net 4.5+)

    static async IAsyncEnumerable<bool> GetBoolsAsync() 
    {
        yield return await Task.FromResult(true);
    }
于 2020-01-14T02:18:10.647 回答