並列処理ってなんぞや（.NET）

## 0. なぜこんなことを書くのか
並列処理とは何なのか、調べたのでアウトプットとしてここに残します。
ドキュメントを読む練習も兼ねているので、参考資料は主に[Microsoftのドキュメント](https://learn.microsoft.com/ja-jp/dotnet/)になります
## 1. 並列処理とは

> 複数のタスクが異なるCPUコアで同時に実行されること。

計算処理系などの比較的小さくて独立した処理を別々のコアで実行することで、複数コアを持つハードウェアのパフォーマンスを引き出すための手法。

### 1-1. 間違えやすい単語
- **並行処理**

> 並行処理とは、複数のプロセスが実行可能状態であること。

**実際には同時にプロセスが動いていなくても、人間の目には同時に処理が行われているように見えている**。マルチタスクOSではシングルコアで各プロセスをナノ秒ごとのタイムスライスで区切って高速に切り替えながら1処理ずつ行っている。

- **非同期処理**

根幹として、非同期処理というものがベースにあり、その用途やシナリオによってバックグラウンド処理、並列処理と分かれるイメージ。

## 2. .NET Frameworksでの並列処理

### 2-1. Parallel.For

Parallel.For(Int32, Int32, ParallelOptions, Action<Int32>)

`第1引数` Int32
開始インデックス

`第2引数` Int32
終了インデックス

`第3引数` ParallelOptions
この操作の動作を構成するオブジェクト

`第4引数` Action
1回のイテレーションにつき1回呼び出されるデリゲート

`戻り値` 
完了したループの部分に関する情報を格納している構造

- 具体例
```c#:c#
using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Parallel.For(0, 10, i =>
        {
            Process(i);
        });
    }

    static void Process(int i)
    {
        Console.WriteLine($"Processing number: {i}");
        // シミュレーション用の待機
        System.Threading.Thread.Sleep(1000);
    }
}
```

### 2-2. Parallel.ForEach

Parallel.ForEach<TSource>(IEnumerable<TSource>, ParallelOptions, Action<TSource>)

`第1引数` IEnumerable
ソース内のデータ型

`第2引数` ParallelOptions
この操作の動作を構成するオブジェクト

`第3引数` Action
1回のイテレーションにつき1回呼び出されるデリゲート

`戻り値` 
完了したループの部分に関する情報を格納している構造

- 具体例
```c#:c#
using System; 
using System.Collections.Generic; 
using System.Threading.Tasks; 
class Program 
{
    static void Main() 
    { 
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; 
        Parallel.ForEach(numbers, number => { Process(number); }); 
    } 
    
    static void Process(int number) 
    { 
        Console.WriteLine($"Processing number: {number}"); // シミュレーション用の待機
        System.Threading.Thread.Sleep(1000);
    }
}
```

### 2-3. Parallel.Invoke
Parallel.Invoke(ParallelOptions, Action[])

`第1引数` ParallelOptions
この操作の動作を構成するオブジェクト

`第2引数` Action[]
実行対象のアクションの配列

- 具体例
```c#:c#
using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Parallel.Invoke(
            () => Process("Task 1"),
            () => Process("Task 2"),
            () => Process("Task 3")
        );
    }

    static void Process(string taskName)
    {
        Console.WriteLine($"{taskName} is running");
        // シミュレーション用の待機
        System.Threading.Thread.Sleep(1000);
    }
}

```

### 2-4. ParallelOptions
- **CancellationToken**
並列処理を途中でキャンセルするための仕組み
```c#:C#
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {
        var cts = new CancellationTokenSource();
        var options = new ParallelOptions { CancellationToken = cts.Token };

        // 別のスレッドで一定時間後にキャンセルを実行
        Task.Run(() =>
        {
            Thread.Sleep(2000); // 2秒待機
            cts.Cancel();
        });

        try
        {
            Parallel.For(0, 10, options, i =>
            {
                Console.WriteLine($"Processing number: {i}");

                Thread.Sleep(1000);
                options.CancellationToken.ThrowIfCancellationRequested();
            });
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Operation was canceled.");
        }
    }
}

```
- **MaxDegreeOfParallelism**
並列処理の最大スレッド数を指定するためのもの
```c#:C#
ParallelOptions option = new ParallelOption();
option.MaxDegereeOfParallelism = 2;

Parallel.For(0, 100, option, i =>
{
    Console.Write(i + ",");
});
```

- **TaskScheduler**
このParallelOptionsインスタンスに関連付けられているTaskSchedulerを取得または設定する。このプロパティをnullに設定すると、現在のスケジューラーが使用される。

## あとがき
調べた感想としては、「ほえぇ、そんなのがあるんだ」って感じです。
次は実際にコードを組み、その恩恵を感じたいと思います。
## 参考文献

https://learn.microsoft.com/ja-jp/dotnet/