Skip to content

Commit f63df2e

Browse files
authored
Add more information for AsyncFixer05
1 parent fc3d4a6 commit f63df2e

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

docs/vsixDoc.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,26 @@ Inside a *using* block, developers insert a fire & forget async call which uses
2828

2929
### AsyncFixer05: Downcasting from a nested task to an outer task.
3030

31-
Downcasting from a nested task (*Task<Task>*) to a *Task* or awaiting a nested task is dangerous. There is no way to wait for and get the result of the child task.
31+
Downcasting from a nested task (*Task<Task>*) to a *Task* or awaiting a nested task is dangerous. There is no way to wait for and get the result of the child task. This usually occurs when mixing `async/await` keywords with the old threading APIs such as `TaskFactory.StartNew`. Here is an example:
32+
33+
```
34+
async Task foo()
35+
{
36+
Console.WriteLine("Hello");
37+
await Task.Factory.StartNew(() => Task.Delay(1000));
38+
Console.WriteLine("World");
39+
}
40+
```
41+
A developer might expect one-second latency between "Hello" and "World" lines. However, those strings will be printed instantaneously without any latency. The reason is that we await `Task<Task>`, which is the return type of `StartNew` call. When we await `Task<Task>`, the inner task is returned which is the result of `Task.Delay` call. As we do not await the inner task, we do not see the effect of the delay call. There are three possible fixes:
42+
43+
1. We can await the inner task as well:
44+
45+
`await (await Task.Factory.StartNew(() => Task.Delay(1000)));`
46+
47+
2. We can use `Unwrap` to expose the inner task to the `await` expression:
48+
49+
`await Task.Factory.StartNew(() => Task.Delay(1000)).Unwrap();`
50+
51+
3. If you do not have reasons to use `TaskFactory.StartNew` such as `TaskCreationOptions` and a custom `TaskScheduler`, we should always use `Task.Run` to automatically unwrap the inner task.
52+
53+
`await Task.Run(() => Task.Delay(1000));`

0 commit comments

Comments
 (0)