【C#】async / await を使って非同期処理を実行する方法

基本的な非同期処理の実装は Task を使用することで行うことができますが、GUIを改善するうえでは asnyc / await についても知っておく必要があります。この記事ではもう一つの重要な実装方法である async / await を使う方法をサンプルを通して解説していきます。async / await を使用すれば快適な GUI のアプリケーションを開発できるので、押さえておくべき内容です。

async / await を使った処理とは

async / await を使ったプログラミングでは処理部分に await を指定することで、スレッドに依頼した処理が完了するまで以降の処理を待機させることができる特性があります。メインスレッド(UI スレッド)は処理をブロックされることなく継続できるのがメリットです。await を使用するにはメソッドのシグネチャーに async を付与する必要があります。

C#  における同期・非同期の処理を実現したい場合は、async / await で解決できるケースが多いため、この記述方法をしっかりマスターできれば実務でも十分に対応できます。async / await を利用した処理は、同期的に動くため処理の順序が崩壊せず、秩序をもって動作させることが可能となります。

async / await の使い方のサンプル

async / await は C# で非同期処理を記述する際に、とても有効性のあるものです。特に GUI との親和性が高く、より使いやすい UI を提供するために使われることが多いです。まずは GUI と絡めずに、これまでと同様にコンソールアプリケーションで使い方を解説していきます。

Console.WriteLine($"作業を依頼します。");
DoAsync(new List<string>() { "花子", "太郎" });
Console.WriteLine($"作業の依頼が完了しました。");
Console.ReadLine();

static async void DoAsync(List<string> names)
{
    foreach(var name in names)
    {
        var res = await Task.Run(() =>
        {
            Console.WriteLine($"{name}さんが大変な作業を開始します。");
            Thread.Sleep(3000);
            Console.WriteLine($"{name}さんが大変な作業をしています。");
            Thread.Sleep(3000);
            Console.WriteLine($"{name}さんの作業が完了しました。");
            return true;
        });
    }
    Console.WriteLine($"{names.Count}人の処理が完了しました。");
}

見やすいサンプルではありませんが、async と await を解説します。async / await を使用するには、メソッドのシグネチャに async を付与します。サンプル内では「static async void DoAsync(List<string> names)」としています。

メソッドのシグネチャーに async を付与することで、メソッド内で await を使用できます。処理部分では await キーワードを使用することで、await を記述した以降は処理が終わってからでないと実行されなくなります。実行結果は以下となります。

作業を依頼します。
作業の依頼が完了しました。
花子さんが大変な作業を開始します。
花子さんが大変な作業をしています。
花子さんの作業が完了しました。
太郎さんが大変な作業を開始します。
太郎さんが大変な作業をしています。
太郎さんの作業が完了しました。
2人の処理が完了しました。

実際に非同期的な処理は DoAsync メソッドで行っています。await を使っているのは「var res = await Task.Run();」の部分です。本来、Task で処理を投げてしまうと処理がそのまま流れていってしまうので、花子さんと太朗さんの処理は同時並行で処理が行われるはずです。

そこを同期的な処理(逐次的な処理)にするために await を使っています。await を使用すると処理が次に行かずに、処理終了までその場で待機させることができます。花子さんの処理がすべて終わってから太朗さんの処理が流れるようになっているんですね。

async と await のメリット(というか、非同期処理を使用するメリット)は UI と絡めたときに発揮される便利な非同期処理なので、書き方・使い方の基礎的な部分を解説しました。ぜひとも活用してみてくださいね。