您有竞争条件,因为您不知道线程完成的顺序。
为每个线程使用单独的局部变量,您在线程构造函数中分配该变量,类似于您刚才使用response
.
然后等待所有线程使用.Join()
:
t1.Join();
t2.Join();
t3.Join();
response
然后在所有Join()
调用返回后使用局部变量进行设置。
但是,我会改用任务。这是一个例子。它在不同的线程中运行三个不同的方法,每个方法都有不同的返回类型:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
private void run()
{
// Using tasks directly:
var task1 = Task<int>.Factory.StartNew(methodOne);
var task2 = Task<string>.Factory.StartNew(methodTwo);
var task3 = Task<double>.Factory.StartNew(methodThree);
// Alternatively:
// var task1 = Task.Run(new Func<int>(methodOne));
// var task2 = Task.Run(new Func<string>(methodTwo));
// var task3 = Task.Run(new Func<double>(methodThree));
string result = string.Format
(
"Task 1: {0}, Task 2: {1}, Task 3: {2}",
task1.Result, // Accessing Task.Result automatically
task2.Result, // waits for the task to complete.
task3.Result
);
Console.WriteLine(result);
// Alternatively, you can use tasks indirectly via Parallel.Invoke().
// You might find this more readable and less typing:
int r1 = 0;
string r2 = null;
double r3 = 0;
Parallel.Invoke
(
() => r1 = methodOne(),
() => r2 = methodTwo(),
() => r3 = methodThree()
);
result = string.Format
(
"Task 1: {0}, Task 2: {1}, Task 3: {2}",
r1,
r2,
r3
);
Console.WriteLine(result);
}
static int methodOne()
{
Thread.Sleep(1000);
return 1;
}
static string methodTwo()
{
Thread.Sleep(750);
return "two";
}
static double methodThree()
{
Thread.Sleep(500);
return 3.0;
}
static void Main(string[] args)
{
new Program().run();
}
}
}
无论您采用哪种方法,重要的是您不应该将结果直接分配给response
线程或任务内部 - 等到所有线程或任务完成后再将结果分配给response
.