「C#.NET」非同期処理の基礎「await」を初心者向けに徹底解説

2024年11月21日木曜日

キーワード(構文) スレッド 基本

t f B! P L

名前空間: System.Threading.Tasks

await

自己紹介

こんにちは。私は「await」です。私は双子の妹「async」と共にあなたのコードに優雅な調和をもたらし、非同期処理の待機を美しく実現するお手伝いをいたします。私はまるで舞台上の演出家のように、処理の順序を見極め、最適なタイミングで次のステップへ導きます。

基本機能

私の役割は、非同期タスクの完了を待ちつつ、他の処理をブロックしないことです。これにより、あなたのプログラムはスムーズに動作を続けながら、必要な結果を効率的に取得できます。例えば、Web APIからデータを取得する場合、結果が戻るまで他の作業を続けることが可能です。

役割と重要性

「await」は非同期タスクを一時停止し、完了したらその続きを実行する魔法のようなキーワードです。しかし、使い方を誤ると、非同期処理のパフォーマンスを損ねることがあります。そのため、私は適切な場所でのみ力を発揮します。

注意点1: Task.Resultとの違い

「await」を使わずに「Task.Result」を使用して結果を取得すると、タスクが完了するまでスレッドがブロックされます。この方法は、特にUIスレッドで使用するとアプリがフリーズする原因になります。一方、「await」は非同期タスクが完了するまで効率的に待機し、スレッドを解放します。

注意点2: 非同期処理の適切な設計

すべての非同期処理に「await」を追加するのは簡単ですが、必ずしも最適ではありません。非同期処理の設計は、タスクの性質やアプリケーションの目的を考慮する必要があります。

注意点3: エラーハンドリング

非同期処理中に例外が発生する場合があります。「await」を使用する際には、try-catch文で適切にエラーハンドリングを行いましょう。例外を無視すると、プログラムの動作が予期せぬ結果を引き起こす可能性があります。

サンプルコード

以下に「await」を使用したコードと、Task.Resultを使用した場合の違いを示すコードを記載します。

C#
using System;
using System.Net.Http;
using System.Threading.Tasks;

public class AwaitExample
{
    // 非同期メソッドでawaitを使用する場合
    public async Task<string> FetchDataWithAwaitAsync()
    {
        // HttpClientをusingで管理し、リソース解放を確実にする
        using (HttpClient client = new HttpClient())
        {
            // 非同期処理でURLからデータを取得
            string result = await client.GetStringAsync("https://example.com");
            return result;
        }
    }

    // Task.Resultを使用する場合
    public string FetchDataWithTaskResult()
    {
        // HttpClientをusingで管理
        using (HttpClient client = new HttpClient())
        {
            // 非同期メソッドの結果をTask.Resultで取得(ブロッキング発生の可能性あり)
            string result = client.GetStringAsync("https://example.com").Result;
            return result;
        }
    }
}

class Program
{
    // Mainメソッド(エントリーポイント)
    static async Task Main(string[] args)
    {
        // AwaitExampleクラスのインスタンス作成
        AwaitExample example = new AwaitExample();

        // awaitを使用した非同期処理の結果取得
        string awaitResult = await example.FetchDataWithAwaitAsync();
        // 結果をコンソールに表示
        Console.WriteLine("Await Result: " + awaitResult);

        // Task.Resultを使用した同期的な処理の結果取得
        string taskResult = example.FetchDataWithTaskResult();
        // 結果をコンソールに表示
        Console.WriteLine("Task.Result: " + taskResult);
    }
}
    

解説

このコードでは、「FetchDataWithAwaitAsync」メソッドで「await」を使用した場合、非同期タスクが効率的に処理されます。一方、「FetchDataWithTaskResult」メソッドでは「Task.Result」を使用しています。この方法ではタスクが完了するまでスレッドがブロックされるため、アプリケーションがフリーズするリスクがあります。非同期処理では「await」を使用することで、スムーズで効率的なコードを実現できます。


このブログを検索

QooQ