C# 在线程方法中关闭值
您好,我正在尝试在线程lambda方法中传递循环的当前索引并打印它。该方法将只打印索引的最后一个值C# 在线程方法中关闭值,c#,multithreading,closures,C#,Multithreading,Closures,您好,我正在尝试在线程lambda方法中传递循环的当前索引并打印它。该方法将只打印索引的最后一个值 class Program { public static EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset); public static EventWaitHandle autohandle = new EventWaitHandle(false, Event
class Program {
public static EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);
public static EventWaitHandle autohandle = new EventWaitHandle(false, EventResetMode.AutoReset);
static readonly int ThreadNum=3;
static void Main(string[] args) {
object lk = new object();
new Thread(() => {
while (true) {
var key = Console.ReadKey();
if(key.Key==ConsoleKey.A) {
handle.Set();
} else {
handle.Reset();
}
Thread.Sleep(3000);
}
}).Start();
for(int i=0;i<ThreadNum;i++) {
new Thread(() => {
int val = i;
Console.WriteLine($"Thread:{val} created");
while (true) {
handle.WaitOne();
Console.WriteLine($"From thread:{val}");
Thread.Sleep(1000);
}
}).Start();
}
Console.WriteLine("Hello World!");
}
}
类程序{
public static EventWaitHandle=new EventWaitHandle(false,EventResetMode.AutoReset);
public static EventWaitHandle autohandle=新的EventWaitHandle(false,EventResetMode.AutoReset);
静态只读int-ThreadNum=3;
静态void Main(字符串[]参数){
对象lk=新对象();
新线程(()=>{
while(true){
var key=Console.ReadKey();
if(key.key==ConsoleKey.A){
handle.Set();
}否则{
handle.Reset();
}
睡眠(3000);
}
}).Start();
对于(int i=0;i{
int val=i;
WriteLine($“线程:{val}已创建”);
while(true){
handle.WaitOne();
WriteLine($”来自线程:{val}”);
睡眠(1000);
}
}).Start();
}
控制台。WriteLine(“你好,世界!”);
}
}
有人能给我解释一下为什么我只能得到索引的最后一个值。我知道索引会被关闭(创建了一个复制索引值的类)但是当第一次迭代进入thread方法时,它应该clojure i=0并保持这种状态。我认为您看到的行为是因为循环在分配局部变量“val”之前进行迭代。因此,在发表声明时
int val = i;
第一次执行时,循环已经迭代了3次,因此将“val”设置为i的最后一个值。
当我运行它时,由于线程创建的相对速度,我得到了可变的行为。
为了获得我认为您想要的行为,您需要在本地捕获循环迭代的计数,如下所示
class Program
{
public static EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);
public static EventWaitHandle autohandle = new EventWaitHandle(false, EventResetMode.AutoReset);
static readonly int ThreadNum = 3;
static void Main(string[] args)
{
object lk = new object();
new Thread(() => {
while (true)
{
var key = Console.ReadKey();
if (key.Key == ConsoleKey.A)
{
handle.Set();
}
else
{
handle.Reset();
}
Thread.Sleep(3000);
}
}).Start();
for (int i = 0; i < ThreadNum; i++)
{
int temp = i;
new Thread(() => ThreadMethod(temp)).Start();
}
Console.WriteLine("Hello World!");
}
private static void ThreadMethod(object obj)
{
int val = (int)obj;
Console.WriteLine($"Thread:{val} created");
while (true)
{
handle.WaitOne();
Console.WriteLine($"From thread:{val}");
Thread.Sleep(1000);
}
}
}
类程序
{
public static EventWaitHandle=new EventWaitHandle(false,EventResetMode.AutoReset);
public static EventWaitHandle autohandle=新的EventWaitHandle(false,EventResetMode.AutoReset);
静态只读int-ThreadNum=3;
静态void Main(字符串[]参数)
{
对象lk=新对象();
新线程(()=>{
while(true)
{
var key=Console.ReadKey();
if(key.key==ConsoleKey.A)
{
handle.Set();
}
其他的
{
handle.Reset();
}
睡眠(3000);
}
}).Start();
对于(int i=0;iThreadMethod(temp)).Start();
}
控制台。WriteLine(“你好,世界!”);
}
私有静态无效线程方法(对象obj)
{
int val=(int)obj;
WriteLine($“线程:{val}已创建”);
while(true)
{
handle.WaitOne();
WriteLine($”来自线程:{val}”);
睡眠(1000);
}
}
}
您的可能副本确实是对的。这就是我所体验的..关于控制台第一次打印的内容的串行代码执行。