DisposeAsync
メソッドがあればawait using(){}
時に実行する。
成果物
情報源
DisposeAsync
メソッド
await using(){}
時に自動で呼び出される- 戻り値は
await
できるなら何でもいい - インスタンスメソッドのみ可
コード
0
using System; using System.Threading.Tasks; namespace AsyncUsing { class Program { static async Task Main(string[] args) { await using(var x = new A()) { Console.WriteLine("Hello Async Using !!"); } } struct A { // Enumerable必須 public A GetAsyncEnumerator() => this; // Enumerator必須 public int Current => 0; public ValueTask<bool> MoveNextAsync() { Console.WriteLine("MoveNextAsync"); return new ValueTask<bool>(false); } // 未実装なら呼ばれない public ValueTask DisposeAsync() { Console.WriteLine("DisposeAsync"); return default; } } } }
$ dotnet run Hello Async Using !! DisposeAsync
1
using System; using System.Threading.Tasks; using System.Reflection; namespace AsyncUsing { class Code1 { public async Task Run() { await using(var x = new A()) { Console.WriteLine($"{this.GetType().Name}"); } } class A { public ValueTask DisposeAsync() { Console.WriteLine($"{MethodBase.GetCurrentMethod().Name}"); return default; } } } }
2
using System; using System.Threading.Tasks; using System.Reflection; namespace AsyncUsing { class Code2 { public async Task Run() { await using(var x = new A()) { Console.WriteLine($"{this.GetType().Name}"); } } class A { public MyAwaitable DisposeAsync() { Console.WriteLine($"{MethodBase.GetCurrentMethod().Name}"); return default; } } struct MyAwaitable { public ValueTaskAwaiter GetAwaiter() => default; } } }
- ValueTaskAwaiter
- この ValueTask の継続アクションをスケジュール設定します。
所感
以前から終了処理を表現するものとしてusing(){}
記法があった。いちいちDispose()
を呼び出さなくとも、ブロック終了時に自動で呼出してくれる。
今回のawait using(){}
は、それの非同期版。
ValueTaskAwaiterとかはよくわからん。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux