c# - async/await whenall 立即返回

标签 c# .net async-await task-parallel-library

我有这个“简单”的测试代码...(不要担心类方法的奇怪使用...)

我试图捕获 Task<>错综复杂...我想我对Task<>.Start()有一点了解/Task<>.Result模式(也许因为它更像“旧”Thread.Start()?),但一旦我觉得捕获了一些东西(所以我扔进await关键字)...然后所有的东西再次纠缠:-(

为什么我的代码在第一个任务完成后立即返回?为什么它不等待 Task.WhenAll()

static BigInteger Factorial(BigInteger factor)
{
    BigInteger factorial = 1;
    for (BigInteger i = 1; i <= factor; i++)
    {
        factorial *= i;
    }
    return factorial;
}

private class ChancesToWin
{
    private int _n, _r;

    public ChancesToWin(int n, int r)
    {
        _n = n;
        _r = r;
    }

    private Task<BigInteger> CalculateFactAsync(int value)
    {
        return Task.Factory.StartNew<BigInteger>(() => Factorial(value));
    }

    public async Task<BigInteger> getFactN()
    {
        BigInteger result = await CalculateFactAsync(_n);
        return result;
    }

    public async Task<BigInteger> getFactN_R()
    {
        BigInteger result = await CalculateFactAsync(_n - _r);
        return result;
    }

    public async Task<BigInteger> getFactR()
    {
        BigInteger result = await CalculateFactAsync(_r);
        return result;
    }

}

private async static void TaskBasedChancesToWin_UseClass()
{
    int n = 69000;
    int r = 600;

    List<Task<BigInteger>> tasks = new List<Task<BigInteger>>();

    ChancesToWin ctw = new ChancesToWin(n, r);

    tasks.Add(ctw.getFactN());
    tasks.Add(ctw.getFactN_R());
    tasks.Add(ctw.getFactR());

    // The getFactR() returns first of the other two tasks... and the code exit!
    BigInteger[] results = await Task.WhenAll(tasks);

    // I don't get here !!!!
    BigInteger chances = results[0] / results[1] * results[2];

    //Debug.WriteLine(chances);
}

static void Main(string[] args)
{
    TaskBasedChancesToWin_UseClass();
}

最佳答案

异步方法同步运行,直到第一次等待,此时它们将控制权返回给调用方法,通常返回一个代表异步操作其余部分的任务。 TaskBasedChancesToWin_UseClass 不会返回任务,因此调用者无法等待它完成。这就是为什么您不应该在事件处理程序之外使用 async void

由于 Main 不会在操作有机会完成之前等待您的应用程序结束。

您通常会使用 await 进行等待,但由于 Main 不能是异步方法,因此您可以使用 Wait 同步阻止任务从 TaskBasedChancesToWin_UseClass 返回:

async static Task TaskBasedChancesToWin_UseClass()
{
    // ...
}

static void Main()
{
    TaskBasedChancesToWin_UseClass().Wait();
}

关于c# - async/await whenall 立即返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33280316/

相关文章:

带有 StringComparer 和德语变音符号的 .net SortedList

.net - 在循环中声明的变量在循环的每次迭代中都保持值

javascript - Aureliajs 在 App Constructor 上等待数据

c# - 无法创建任务 <HttpResponseMessage> "await"

c# - C# 编译器能否区分 I/O 绑定(bind)任务和计算任务?

c# - 将 JObject 转换为 Dictionary<string, object>。可能吗?

C# 使用 LINQ 和 Nullable Boolean

c# - 区分多个 webclient 结果

c# - Linq选择项目,它等于另一个表中的ID

c# - 使用 makecert 创建证书吊销列表 (CRL),然后使用 pvk2pfx 将其捆绑到 .pfx