await await vs Unwrap()

时间:2016-01-15 17:32:23

标签: c# async-await

给出一个方法,如

public async Task<Task> ActionAsync()
{
    ...
}

之间有什么区别
await await ActionAsync();

await ActionAsync().Unwrap();

如果有的话。

2 个答案:

答案 0 :(得分:33)

Unwrap()创建一个新的任务实例,代表每次调用的整个操作。与await相反,以这种方式创建的任务与原始内部任务不同。请参阅Unwrap()文档,并考虑以下代码:

private async static Task Foo()
{
    Task<Task<int>> barMarker = Bar();

    Task<int> awaitedMarker = await barMarker;
    Task<int> unwrappedMarker = barMarker.Unwrap();

    Console.WriteLine(Object.ReferenceEquals(originalMarker, awaitedMarker));
    Console.WriteLine(Object.ReferenceEquals(originalMarker, unwrappedMarker));
}

private static Task<int> originalMarker;
private static Task<Task<int>> Bar()
{
    originalMarker = Task.Run(() => 1);;
    return originalMarker.ContinueWith((m) => m);
}

输出是:

True
False

使用.NET 4.5.1基准测试进行更新:我对两个版本进行了测试,结果表明,使用双await的版本在内存使用方面更好。 我使用Visual Studio 2013内存分析器。测试包括每个版本的100000个调用。

64:

╔══════════════════╦═══════════════════════╦═════════════════╗
║ Version          ║ Inclusive Allocations ║ Inclusive Bytes ║
╠══════════════════╬═══════════════════════╬═════════════════╣
║ await await      ║ 761                   ║ 30568           ║
║ await + Unwrap() ║ 100633                ║ 8025408         ║
╚══════════════════╩═══════════════════════╩═════════════════╝

86:

╔══════════════════╦═══════════════════════╦═════════════════╗
║ Version          ║ Inclusive Allocations ║ Inclusive Bytes ║
╠══════════════════╬═══════════════════════╬═════════════════╣
║ await await      ║ 683                   ║ 16943           ║
║ await + Unwrap() ║ 100481                ║ 4809732         ║
╚══════════════════╩═══════════════════════╩═════════════════╝

答案 1 :(得分:7)

没有任何功能差异。