Threadクラスで非同期処理するメソッドは戻り値を指定できないと思うのですが、クラスのメンバ変数を使えば戻り値のように利用することが可能です。少し強引な気もしますが本記事ではそのサンプルを紹介します。
動作確認環境
- Windows10 x64
- コンソールアプリ(.NETFramework4.8)
- VisualStudio2022
- C#7.3
サンプル
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace wait_for_thread
{
class Program
{
//func2メソッドの戻り値を格納
static List<(int, int, string)> returnValues = new List<(int, int, string)> ();
static void Main(string[] args)
{
//TaskをまとめるListを作成
List<Thread> Threads = new List<Thread>();
//並列で動かすスレッドを生成
for (int i1 = 0; i1 < 5; i1++)
{
object[] paras = { i1, "para" + i1.ToString() };
Thread t = new Thread(new ParameterizedThreadStart(func1));
t.Start(paras);
Threads.Add(t);
}
//全てのスレッドの終了を待機する
for (int i1 = 0; i1 < Threads.Count; i1++)
{
Threads[i1].Join();
}
//func2メソッドの戻り値を全て表示する
for (int i1 = 0; i1 < returnValues.Count; i1++)
{
Console.WriteLine(returnValues[i1].Item1.ToString() + " " + returnValues[i1].Item2.ToString() + " " + returnValues[i1].Item3.ToString());
}
Console.Read();
}
/// <summary>
/// Threadクラスで並列で処理するメソッド。Treadクラスで指定するメソッドには戻り値をつけられない・・・
/// </summary>
/// <param name="para"></param>
static void func1(object para)
{
int i = 0;
string s = "";
(i,s) = func2(para);
//Threadクラスの呼び出し元でこのメソッドで得られた値を利用する(=戻り値)ためにメンバ変数に格納しておく
returnValues.Add(((int)((object[])para)[0], i, s));
}
/// <summary>
/// Treadクラスで指定したメソッドの中にあるメソッドには戻り値をつけることができる
/// </summary>
/// <param name="para"></param>
/// <returns></returns>
static (int,string) func2(object para)
{
return ((int)((object[])para)[0] + 1, ((object[])para)[1].ToString() + " test");
}
}
}