なんだかGoodVibes

日々の勉強メモです。

【C#】Taskを使ってファイルの処理を並列で行う

こんにちは。
本日はC#メモです。

概要

大量のファイル対して同様の処理を行いたい。

その処理には時間のかかる処理AとBが存在するとする。

非同期で処理をして効率よく処理が行えるようにする。


サンプルコード

メイン処理

メイン処理では
ファイルを取得して実際にファイルに対する処理を行うクラスをnewして呼び出します。

ファイルの取得はDirectory.EnumerateFilesを使用しています。
Directory.EnumerateFilesはファイルが見つかり次第返すので、
全てのファイルを検索するまで待機はしません。

あとは.Wait()でタスクが完了するまで待機しています。

var files = Directory.EnumerateFiles(@"./text", "*.txt", SearchOption.AllDirectories);
var manager = new FileManager(files);
manager.Run().Wait();
ファイル処理

各ファイルごとに処理A、処理Bを非同期で実施しています。

Run()メソッドでは、
各ファイルのタスクをリストに格納し、Task.WhenAll()を使用して
全ファイルのタスクが全て完了するのを待機しています。

Process()メソッドでは、
処理Aと処理Bのタスクをリストに格納し、Task.WhenAll()を使用して
2つのタスクが全て完了するのを待機しています。

private class FileManager
{
    private readonly IEnumerable<string> _files;

    public FileManager(IEnumerable<string> files)
    {
        this._files = files;
    }

    public Task Run()
    {
        var tasks = new List<Task>();
        foreach (var file in this._files)
        {
            tasks.Add(this.Process(file));
        }

        return Task.WhenAll(tasks);
    }

    private Task Process(string file)
    {
        var tasks = new List<Task>();

        tasks.Add(Task.Run(() => {
            // 処理A
            var id = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine($"[処理A][{DateTime.Now.ToString("HH:mm:ss.fff")}] ThreadId={id} File={file}");
            Thread.Sleep(TimeSpan.FromSeconds(3));
        }));

        tasks.Add(Task.Run(() => {
            // 処理B
            var id = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine($"[処理B][{DateTime.Now.ToString("HH:mm:ss.fff")}] ThreadId={id} File={file}");
            Thread.Sleep(TimeSpan.FromSeconds(5));
        }));

        return Task.WhenAll(tasks);
    }
}
実行結果

以下のファイルを用意して実行した結果です。
各ファイル、処理A、処理Bが非同期で実施されています。

  • /text/aaa.txt
  • /text/bbb.txt
[処理A][19:47:52.750] ThreadId=6 File=./text/aaa.txt
[処理B][19:47:52.750] ThreadId=5 File=./text/bbb.txt
[処理B][19:47:52.750] ThreadId=7 File=./text/aaa.txt
[処理A][19:47:52.750] ThreadId=4 File=./text/bbb.txt



以上です。