多个线程在C#中调用相同的方法

我有以下C#代码片段,我在其中模拟了我的问题。 在这个程序中,我有一个调用ReadRooms方法的Service函数。 现在我在不同的线程上调用服务方法。 我原以为ServiceCall和ReadRooms方法都会被平分,但是我得到的结果不正确。

在此处输入图像描述

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { public static void ReadRooms(int i) { Console.WriteLine("Reading Room::" + i); Thread.Sleep(2000); } public static void CallService(int i) { Console.WriteLine("ServiceCall::" + i); ReadRooms(i); } static void Main(string[] args) { Thread[] ts = new Thread[4]; for (int i = 0; i  { int temp = i; CallService(temp); }); ts[i].Start(); } for (int i = 0; i < 4; i++) { ts[i].Join(); } Console.WriteLine("done"); Console.Read(); } } } 

你仍然在“捕获循环变量”。 当i已被捕获时,你正在创造一个temp但为时已晚。

试试这个:

 for (int i = 0; i < 4; i++) { int temp = i; // outside the lambda ts[i] = new Thread(() => { //int temp = i; // not here CallService(temp); }); ts[i].Start(); } 

你应该把这一行

 int temp = i; 

在线程创建之前

 for (int i = 0; i < 4; i++) { int temp = i; ts[i] = new Thread(() => CallService(temp)); ts[i].Start(); } 

这样,您将创建将由lambda表达式使用的i的本地副本。

您的线程操作正在关闭变量i而不是其当前值。 因此,线程读取i和for循环中的增量之间存在竞争。 您可以将其作为参数传递:

 ts[i] = new Thread(index => { CallService((int)index); }); ts[i].Start(i); 

或者你可以将temp的副本移动到循环内部而不是线程动作:

 for (int i = 0; i < 4; i++) { int temp = i; ts[i] = new Thread(() => { CallService(temp); }); ts[i].Start(); }