8

从下面的测试我们可以看到当前版本的框架保证输出顺序和输入任务的顺序一致。

async Task<string> GetString1()
{
    await Task.Delay(2000);
    return "1";
}

async Task<string> GetString2()
{
    await Task.Delay(1000);
    return "2";
}

var results = await Task.WhenAll(GetString1(), GetString2());
//now we have results[0] == "1" results[1] == "2"

但是,从文档中我找不到有关此行为的任何信息,这意味着它不是文档保证的。从这个问题的答案的观点来看:

我需要在输出中放置“订单标志”吗?例如将示例代码更改为以下内容:

class OrderTaskResult<T>
{
    public OrderTaskResult(int order, T value)
    {
        this.Order = order;
        this.Value = value;
    }
    public int Order { get; private set; }
    public T Value { get; private set; }
}

async Task<OrderTaskResult<string>> GetString1()
{
    await Task.Delay(2000);
    return new OrderTaskResult<string>(1, "1");
}
4

2 回答 2

17

您正在查看错误重载的文档。

如果您查看实际返回结果的重载,您会看到:

返回任务的Task<TResult>.Result属性将设置为一个数组,其中包含所提供任务的所有结果,其顺序与提供的顺序相同

于 2016-04-06T02:29:02.353 回答
0

回答你的第二个问题,尽管在这种特殊情况下认识到它现在没有实际意义 -

Q2:(可能基于主要意见)根据未记录的行为进行编码真的是不好的做法,尤其是当某些行为几乎不可能改变时?有时您需要添加大量代码以避免未记录的行为。

将给出规范的工程答案 - 这取决于。您需要权衡当前使用更简单代码的好处与将来从脚下猛拉地毯的风险。

一方面,“技术债务”是您可能从阅读中受益的东西,以建立您的直觉 -

技术债务(也称为设计债务或代码债务,但也可能与其他技术努力相关)是软件开发中的一个概念,它反映了由于现在选择简单(有限)解决方案而不是使用更好的方法,需要更长的时间。

另一方面,您可以通过以模块化和松散耦合的方式构建代码库来将风险降低到可接受的程度——如果您遵循 SOLID 设计原则给出的指导,您将无论如何可能正在做。或者,如果您正在采取更实用的路线,您可能会尝试从 Mark Seemann 的Impureim 三明治中尝一尝,这也有助于保持您的核心域逻辑与应用程序细节解耦,这些细节可能会随着下一次炒作或弃用而发生变化特殊的传球技术。

于 2021-10-21T12:58:36.633 回答