如何并行调用同步方法?

问题描述 投票:0回答:1

我需要帮助来理解异步/等待在这种情况下如何工作。 我有4种方法

async Task<int> get1()
{
    await Task.Yield();
    Console.WriteLine("get1");
    return 1;
}

async Task<int> get2()
{
    await Task.Yield();
    Console.WriteLine("get2");
    return 2;
}

async Task<int> get3()
{
    await Task.Yield();
    Console.WriteLine("get3");
    return 3;
}

async Task<int> get4()
{
    await Task.Yield();
    Console.WriteLine("get4");
    return 4;
}

我通过以下方法调用他们

async Task<int> doMultiMethods()
{
    // we have the list of tasks - taskList
    // we have the task that lets us know when all the tasks in that list are completed - resultTask
    // we have the results of the task that waited for all the tasks - resultTask (after resultTask is awaited)
    // we have the results of all the tasks - results
    Task<int> x = get1();
    Task<int> y = get2();
    Task<int> z = get3();
    Task<int> a = get4();
    List<Task<int>> taskList = new List<Task<int>> { x, y, z, a };

    var resultTask = Task.WhenAll(taskList);
    int[]? results = await resultTask;
    //await results;

    if (resultTask.IsCompleted && results.Any())
    {
        foreach (var r in results)
        {
            Console.WriteLine(r);
        }
        Console.WriteLine("Done");
    }

    return 0;
}

我的输出如下所示,每次调用时前 4 行都是“随机”的。

get4
get3
get1
get2
1
2
3
4
Done

我不明白的是为什么我需要等待Task.Yield()来获取异步运行的方法。如果我从所有方法中删除所有等待 Task.Yield() ,我的代码每次都会按顺序输出 get 方法(输出的前 4 行),让我相信它们正在同步运行。

调用方法以使它们异步运行的正确方法是什么?我的主要问题是警告

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

并确保它们实际上是异步运行的。

c# asynchronous async-await
1个回答
1
投票

我应该使用 Task.Run 来调用我的 get 方法,并且不要将它们定义为异步。如本页所示 - https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios

async Task<int> DoMultiMethodsAsync2()
{
    Task<int> x = Task.Run(() => Get1());
    Task<int> y = Task.Run(() => Get2());
    Task<int> z = Task.Run(() => Get3());
    Task<int> a = Task.Run(() => Get4());
    List<Task<int>> taskList = new List<Task<int>> { x, y, z, a };

    var resultTask = Task.WhenAll(taskList);
    int[]? results = await resultTask;
    //await results;

    if (resultTask.IsCompleted && results.Any())
    {
        foreach (var r in results)
        {
            Console.WriteLine(r);
        }
        Console.WriteLine("Done");
    }

    return 0;
}


int Get1()
{
    Console.WriteLine("Get1");
    return 1;
}

int Get2()
{
    Console.WriteLine("Get2");
    return 2;
}

int Get3()
{
    Console.WriteLine("Get3");
    return 3;
}

int Get4()
{
    Console.WriteLine("Get4");
    return 4;
}

样本输出

Get3
Get2
Get4
Get1
1
2
3
4
Done
© www.soinside.com 2019 - 2024. All rights reserved.