线程启动传递的整数本身发生了超出应有的变化
Thread start passed integer changes itself beyond what it should be
我不知道这是怎么回事。我正在尝试通过生成 100 个线程来不断访问它来测试 class 的线程安全性,但似乎我的匿名方法参数正在将自身更改为它们不应该的值,我对为什么感到困惑。由于我不知道发生了什么,我将 post 测试涉及的所有功能。不知何故,我最终以 "Thread 98" 获取参数 "num = 100"... 这不应该是可能的,我不知道正在发生什么样的 hokey pokey 正在改变整数。 (在方法 "ThreadWriting(int num)" 中,您会看到我检查 "num" 是否等于 100 的地方,我在其中放置了一个断点以捕获该行为中的违规线程,它每次都会中断。否则它在数组 "counts" 上抛出一个 "IndexOutofRangeException"。我只是想看看我的线程是否通常能平等地访问 class 他们都试图同时使用。
public delegate void TempDel();
public TempDel InvokeTest;
public void TRTest3(Form1 sender)
{
InvokeTest = new TempDel(UpdateInvoke);
Thread t = new Thread(() => ConsoleUpdateTest(sender));
t.IsBackground = true;
t.Start();
POConsole.Instance.MaxLines = 20;
for(int i = 0; i < 100; i++)
{
Thread t2 = new Thread(() => ThreadWriting(i));
t2.IsBackground = true;
t2.Name = String.Format("Thread {0}", i);
t2.Start();
}
}
public ulong[] counts = new ulong[100];
public void ThreadWriting(int num)
{
if(num == 100)
{
bool stop = true;
}
while (true)
{
POConsole.Instance.WriteLine("Hello from Thread " + num);
counts[num]++;
}
}
public void ConsoleUpdateTest(Form1 sender)
{
while(true)
{
sender.Invoke(InvokeTest);
Thread.Sleep(5);
}
}
public void UpdateInvoke()
{
QuickTestBox.Text = POConsole.Instance.FullFeed;
}
我的所有线程都已命名,如您所见,其中 none 个收到名称 "Thread 100" 所以我不知道其他线程之一如何传递参数 100或者参数可能以某种方式损坏。
显然我的线程安全检查在某些方面不是线程安全的?
这是一个简单的闭包问题,您不应该将 for 循环计数器用作线程参数问题,问题发生在此处,for 循环和线程执行速度不同 运行,因此值我可以为多个线程更改:
for(int i = 0; i < 100; i++)
{
Thread t2 = new Thread(() => ThreadWriting(i));
t2.IsBackground = true;
t2.Name = String.Format("Thread {0}", i);
t2.Start();
}
使用以下修改,从循环计数器创建局部变量
for(int i = 0; i < 100; i++)
{
int j = i;
Thread t2 = new Thread(() => ThreadWriting(j));
t2.IsBackground = true;
t2.Name = String.Format("Thread {0}", j);
t2.Start();
}
我不知道这是怎么回事。我正在尝试通过生成 100 个线程来不断访问它来测试 class 的线程安全性,但似乎我的匿名方法参数正在将自身更改为它们不应该的值,我对为什么感到困惑。由于我不知道发生了什么,我将 post 测试涉及的所有功能。不知何故,我最终以 "Thread 98" 获取参数 "num = 100"... 这不应该是可能的,我不知道正在发生什么样的 hokey pokey 正在改变整数。 (在方法 "ThreadWriting(int num)" 中,您会看到我检查 "num" 是否等于 100 的地方,我在其中放置了一个断点以捕获该行为中的违规线程,它每次都会中断。否则它在数组 "counts" 上抛出一个 "IndexOutofRangeException"。我只是想看看我的线程是否通常能平等地访问 class 他们都试图同时使用。
public delegate void TempDel();
public TempDel InvokeTest;
public void TRTest3(Form1 sender)
{
InvokeTest = new TempDel(UpdateInvoke);
Thread t = new Thread(() => ConsoleUpdateTest(sender));
t.IsBackground = true;
t.Start();
POConsole.Instance.MaxLines = 20;
for(int i = 0; i < 100; i++)
{
Thread t2 = new Thread(() => ThreadWriting(i));
t2.IsBackground = true;
t2.Name = String.Format("Thread {0}", i);
t2.Start();
}
}
public ulong[] counts = new ulong[100];
public void ThreadWriting(int num)
{
if(num == 100)
{
bool stop = true;
}
while (true)
{
POConsole.Instance.WriteLine("Hello from Thread " + num);
counts[num]++;
}
}
public void ConsoleUpdateTest(Form1 sender)
{
while(true)
{
sender.Invoke(InvokeTest);
Thread.Sleep(5);
}
}
public void UpdateInvoke()
{
QuickTestBox.Text = POConsole.Instance.FullFeed;
}
我的所有线程都已命名,如您所见,其中 none 个收到名称 "Thread 100" 所以我不知道其他线程之一如何传递参数 100或者参数可能以某种方式损坏。
显然我的线程安全检查在某些方面不是线程安全的?
这是一个简单的闭包问题,您不应该将 for 循环计数器用作线程参数问题,问题发生在此处,for 循环和线程执行速度不同 运行,因此值我可以为多个线程更改:
for(int i = 0; i < 100; i++)
{
Thread t2 = new Thread(() => ThreadWriting(i));
t2.IsBackground = true;
t2.Name = String.Format("Thread {0}", i);
t2.Start();
}
使用以下修改,从循环计数器创建局部变量
for(int i = 0; i < 100; i++)
{
int j = i;
Thread t2 = new Thread(() => ThreadWriting(j));
t2.IsBackground = true;
t2.Name = String.Format("Thread {0}", j);
t2.Start();
}