从下面的测试中,我们可以看到当前版本的框架保证输出顺序与输入任务相同。
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");
}
您正在查看文档中是否存在错误的重载。
如果你看看实际返回结果的过载,你会看到:
返回任务的
Task<TResult>.Result
属性将被设置为一个数组,该数组包含所提供任务的所有结果,其顺序与提供的顺序相同
回答你的第二个问题,尽管在这个特殊的情况下,识别它现在是没有意义的——
Q2:(可能是基于主要观点)根据未记录的行为进行编码真的是一种糟糕的做法吗,尤其是当某些行为几乎没有改变的可能性时?有时您需要添加大量代码来避免未记录的行为。
将给出规范的工程答案——这取决于情况。你需要权衡一下目前使用更简单代码的好处和将来被从你脚下拽出地毯的风险。
一方面;技术性债务;你可能会从阅读中受益,从而在这里建立你的直觉-
技术债务(也称为设计债务或代码债务,但也可能与其他技术工作有关)是软件开发中的一个概念,反映了由于现在选择简单(有限)的解决方案而不是使用需要更长时间的更好方法而导致的额外返工的隐含成本。
另一方面,通过以模块化和松散耦合的方式构建代码库,您或许可以将风险降低到可接受的程度——如果您遵循SOLID设计原则给出的指导,您可能无论如何都会这样做。或者,如果你正在走一条更具功能性的路线,你可以试着吃一口Mark Seemann的Impuremi三明治,这也大大有助于保持你的核心域逻辑与应用程序细节的解耦,这些细节可能会随着下一次对特定传递技术的炒作或抨击而发生变化。