W sieci jest wiele materiałów na temat konstrukcji async-away. Postanowiłem zbadać kilka ciekawostek. Użycie async bez away Rozważmy kod
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
using System; using System.Threading.Tasks; public class C { public async void Pierwsza() { var i = await test(); } public async void Druga() { var i = test().Result; } Task<int> test() { return Task.Run(() => { return 1; }); } } |
Metoda „Pierwsza” jest napisana zgodnie ze sztuką. Budowa metody „Druga” budzi sprzeciw kompilatora:
|
(8,22,8,27): Warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. |
Użyłem strony http://tryroslyn.azurewebsites.net aby obnażyć prawdę. Oto prawdziwy „kod pod spodem” (fragment)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
[AsyncStateMachine(typeof(C.<Pierwsza>d__1))] public void Pierwsza() { C.<Pierwsza>d__1 <Pierwsza>d__; <Pierwsza>d__.<>4__this = this; <Pierwsza>d__.<>t__builder = AsyncVoidMethodBuilder.Create(); <Pierwsza>d__.<>1__state = -1; AsyncVoidMethodBuilder <>t__builder = <Pierwsza>d__.<>t__builder; <>t__builder.Start<C.<Pierwsza>d__1>(ref <Pierwsza>d__); } [AsyncStateMachine(typeof(C.<Druga>d__1))] public void Druga() { C.<Druga>d__1 <Druga>d__; <Druga>d__.<>4__this = this; <Druga>d__.<>t__builder = AsyncVoidMethodBuilder.Create(); <Druga>d__.<>1__state = -1; AsyncVoidMethodBuilder <>t__builder = <Druga>d__.<>t__builder; <>t__builder.Start<C.<Druga>d__1>(ref <Druga>d__); } |
Zabawa w „znajdź różnice” skutkuje tylko tym, że […]