6
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C# で簡単に await/async に置き換える方法

Posted at

C# で簡単に await/async に置き換える方法

C# には便利な EventHandler というものがあります。
とある処理が完了した時点で事前に登録されているイベントハンドラーが実行されるものです。

例えば以下のような Process を await/async に置き換えてみます。
(※Process.WaitForExitAsync があるやんけとかは言わないでください…)

var startInfo = new ProcessStartInfo {
    FileName = "dir",
    UseShellExecute = false,
    ErrorDialog = false,
};

var process = new Process {
    StartInfo = startInfo,
    EnableRaisingEvents = true,
};

process.Exited += (sender, args) => {
    // プロセス終了
};

これを await で待機可能にするには…

public static Task<int> RunAsync(this Process process)
{
    var exited = new TaskCompletionSource<int>();

    process.Exited += (sender, args) => {
        exited.TrySetResult(process.ExitCode);
    };

    if (!process.Start()) {
        throw new InvalidOperationException($"Could not start process: {process}");
    }

    return exited.Task;
}

みたいな拡張機能を作成して…

await process.RunAsync();

で待機することが可能です。

新規で作成するクラスの場合 INotifyCompletion やらを使用して初めから待機可能にすることも出来ますが、既存クラスを待機可能にするだけであれば上記の例のように TaskCompletionSource を使えば簡単に待機可能に出来ます。

public static Task<T> ????Async<T>(this ???? awaitable)
{
    var tcs = new TaskCompletionSource<T>();

    // awaitable の非同期処理終了時に tcs.TrySetResult を呼び出す

    return tcs.Task;
}

みたいな感じです。

6
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?