マルチスレッド

C#入門⑥ マルチスレッド

マルチスレッドとは?

マルチスレッドとは、複数の処理を同時並行で実行する仕組み です。
C#では標準ライブラリを利用して、簡単にスレッドやタスクを扱うことができます。

長時間かかる処理を並列実行することで、アプリケーションの応答性を向上させられます。

Threadクラスの利用

最も基本的な方法は Thread クラスを使うやり方です。

using System;
using System.Threading;

class Program
{
    static void Work()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("別スレッド: " + i);
            Thread.Sleep(500);
        }
    }

    static void Main()
    {
        Thread t = new Thread(Work);
        t.Start();

        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("メインスレッド: " + i);
            Thread.Sleep(500);
        }
    }
}

Taskクラスによる非同期処理

C#では Task クラスを使うのが一般的です。
非同期処理を簡潔に書けるため、モダンなC#プログラミングではこちらが推奨されます。

using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Task.Run(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("タスク: " + i);
            }
        });

        Console.WriteLine("メイン処理");
    }
}

async / await の利用

async / await を使うと、非同期処理を同期処理のように書けます。

using System;
using System.Threading.Tasks;

class Program
{
    static async Task WorkAsync()
    {
        await Task.Delay(1000); // 1秒待機
        Console.WriteLine("非同期処理完了");
    }

    static async Task Main()
    {
        Console.WriteLine("開始");
        await WorkAsync();
        Console.WriteLine("終了");
    }
}

並列処理(Parallelクラス)

複数のループ処理を並列に実行する場合は Parallel.For が便利です。

using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Parallel.For(0, 5, i =>
        {
            Console.WriteLine($"処理 {i} を実行中 (スレッドID: {Task.CurrentId})");
        });
    }
}

注意点:スレッドセーフ

複数のスレッドから同じ変数にアクセスする場合は、競合が発生する可能性があります。
この場合は lock を使って排他制御を行います。

private static object lockObj = new object();
private static int counter = 0;

static void Increment()
{
    for (int i = 0; i < 1000; i++)
    {
        lock (lockObj)
        {
            counter++;
        }
    }
}

まとめ

  • Thread クラスで基本的なマルチスレッド処理が可能
  • Taskasync/await でモダンな非同期処理を実装できる
  • Parallel クラスでループ処理を並列化できる
  • スレッド間でデータを共有する場合は排他制御が必要