C# 非同期メソッドの呼び出しと Task.Delay を利用した処理の実装例

この資料では、C#で非同期メソッドを実装し、Task.Delay を使った遅延処理の実装方法と、他のメソッドからの呼び出し方について解説します。また、非同期メソッドを同期的に呼び出す方法についても説明します。


1. 概要

C#では、async/awaitパターンを使って非同期処理を簡単に実装できます。

  • 非同期メソッドの実装: async修飾子とTaskまたはTask<T>を返すことで非同期メソッドを定義できます。
  • 遅延処理: Task.Delay を利用することで、非同期に一定時間待機することができます。
  • 呼び出し方法: 非同期メソッドは、呼び出し側も非同期メソッドとして定義し、await を使って呼び出すのが一般的です。
  • 同期呼び出し: 場合によっては、非同期メソッドを同期的に呼び出すことも可能ですが、デッドロックに注意が必要です。

2. 非同期メソッドの実装例

以下のコードは、Task.Delay を使って1秒ごとに繰り返し処理を行う非同期メソッドの例です。

using System;
using System.Threading.Tasks;

class Program
{
    // 非同期メソッド(戻り値がない場合は Task を返す)
    static async Task ProcessWithDelayAsync()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Iteration {i}: 処理を実行中...");
            await Task.Delay(1000); // 1秒待機
        }
        Console.WriteLine("非同期処理完了");
    }
}

3. 他のメソッドからの呼び出し方法

非同期メソッドとして呼び出す方法

呼び出し側のメソッドも非同期に定義し、await を使って呼び出すのが一般的な方法です。
以下の例では、CallerMethodAsync 内で ProcessWithDelayAsync を呼び出しています。

using System;
using System.Threading.Tasks;

class Program
{
    // 非同期メソッド(Task を返す)
    static async Task ProcessWithDelayAsync()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Iteration {i}: 処理を実行中...");
            await Task.Delay(1000); // 1秒待機
        }
        Console.WriteLine("非同期処理完了");
    }

    // 非同期メソッドとして呼び出す例
    static async Task CallerMethodAsync()
    {
        Console.WriteLine("CallerMethodAsync 開始");
        await ProcessWithDelayAsync();
        Console.WriteLine("CallerMethodAsync 完了");
    }

    // エントリーポイント(C# 7.1以降なら Main も async に可能)
    static async Task Main(string[] args)
    {
        await CallerMethodAsync();
    }
}

同期的に「単純に」呼び出す方法

非同期メソッドを同期的に呼び出す場合、戻り値の Task に対して Wait() または GetAwaiter().GetResult() を使い、完了を待機する方法があります。
以下はその例です。

using System;
using System.Threading.Tasks;

class Program
{
    // 非同期メソッド(Task を返す)
    static async Task ProcessWithDelayAsync()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Iteration {i}: 処理を実行中...");
            await Task.Delay(1000); // 1秒待機
        }
        Console.WriteLine("非同期処理完了");
    }

    // 同期メソッドから呼び出す例
    static void CallerMethod()
    {
        // Task.Wait() を使って同期的に待機
        ProcessWithDelayAsync().Wait();
        // または、下記のように GetAwaiter().GetResult() を使うことも可能
        // ProcessWithDelayAsync().GetAwaiter().GetResult();
        Console.WriteLine("CallerMethod 完了");
    }

    static void Main(string[] args)
    {
        CallerMethod();
    }
}

注意: 同期的な呼び出しは、UIスレッドや特定の環境でデッドロックの原因となる場合があるため、使用する状況に十分注意してください。


4. 注意点

  • 非同期と同期の選択:
    非同期メソッドは、UIアプリケーションやサーバーアプリケーションで特に有用です。
    可能な限り非同期パターンを利用することが推奨されます。
  • エラーハンドリング:
    非同期メソッド内で例外が発生した場合、呼び出し元で適切にキャッチして処理するようにしましょう。
  • デッドロックの回避:
    同期的に非同期メソッドを呼び出す場合、特にUIアプリケーションなどではデッドロックに注意が必要です。

5. まとめ

  • C#では async/await パターンを使って非同期処理を実装する。
  • Task.Delay を使うことで、非同期に一定時間の遅延処理を実現できる。
  • 他のメソッドから非同期メソッドを呼び出す際は、呼び出し側も非同期に定義して await を使うのが一般的。
  • 必要に応じて、同期メソッドからも .Wait().GetAwaiter().GetResult() を利用して呼び出すことができるが、ブロッキングやデッドロックに注意すること。

以上が、C#における非同期メソッドの呼び出しとTask.Delayを利用した実装例の解説です。

C#,非同期

Posted by hidepon