Unwrap() creates a new instance of the task that represents the entire operation for each call. Unlike await task created in this way is different from the original internal task. See Unwrap () docs and view the following code:
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); }
Exit:
True False
Update with .NET 4.5.1 Performance Test:. I tested both versions, and it turns out that the double await version is better in terms of memory usage. I used the Visual Studio 2013 memory profiler. The test includes 100,000 calls of each version.
64:
ββββββββββββββββββββ¦ββββββββββββββββββββββββ¦ββββββββββββββββββ β Version β Inclusive Allocations β Inclusive Bytes β β βββββββββββββββββββ¬ββββββββββββββββββββββββ¬ββββββββββββββββββ£ β await await β 761 β 30568 β β await + Unwrap() β 100633 β 8025408 β ββββββββββββββββββββ©ββββββββββββββββββββββββ©ββββββββββββββββββ
x86:
ββββββββββββββββββββ¦ββββββββββββββββββββββββ¦ββββββββββββββββββ β Version β Inclusive Allocations β Inclusive Bytes β β βββββββββββββββββββ¬ββββββββββββββββββββββββ¬ββββββββββββββββββ£ β await await β 683 β 16943 β β await + Unwrap() β 100481 β 4809732 β ββββββββββββββββββββ©ββββββββββββββββββββββββ©ββββββββββββββββββ
Leonid Vasilyev
source share