在将一个简单的线程池解决方案放入我的应用程序之前,我正在测试它,但是我看到的结果对我来说没有任何意义。我有一个简单的表单,上面有一个按钮。此按钮启动以下循环:
private void button1_Click(object sender, EventArgs e)
{
MyTestThread oTask = new MyTestThread ();
MyThreadInfo oTaskParameters = new MyThreadInfo();
for (int i = 1; i <= 5; i++)
{
objTaskParameters.MyGuid = Guid.NewGuid();
objTaskParameters.MyNumber = i;
ThreadPool.QueueUserWorkItem(new WaitCallback(objTask.ProcessDataForNTime), objTaskParameters);
}
Console.WriteLine("All threads have been queued for processing...");
}它调用的类看起来像这样。它有一个参数MyThreadInfo类,然后MyTestThread类只循环10秒就结束了。
public class MyThreadInfo
{
public int MyNumber;
}
public class MyTestThread
{
public void ProcessDataForNTime(Object oParameters)
{
//We pass parameters
MyThreadInfo oThread = (MyThreadInfo)oParameters;
int threadNo = oThread.MyNumber;
Console.WriteLine("thread {0} started...", threadNo);
int iN = 10; //Delay for 10 seconds
DateTime dteStart = DateTime.Now;
do
{
System.Threading.Thread.Sleep(1000); //Wait a second before we look again
} while (dteStart.AddSeconds(iN) > DateTime.Now);
Console.WriteLine("thread {0} completed...", threadNo);
}
}我希望结果在我的控制台/输出/调试日志中显示如下所示。当我浏览这个应用程序时,我确实看到了以下内容:
thread 1 started...
thread 2 started...
thread 3 started...
thread 4 started...
thread 5 started...
All threads have been queued for processing...
thread 1 completed...
thread 2 completed...
thread 3 completed...
thread 4 completed...
thread 5 completed...但是,如果我全速运行应用程序,而不遍历代码或断点,它会输出以下内容:
All threads have been queued for processing...
thread 5 started...
thread 5 started...
thread 5 started...
thread 5 started...
thread 5 started...
thread 5 completed...
thread 5 completed...
thread 5 completed...
thread 5 completed...
thread 5 completed...单步执行使其工作的代码是什么?我确实注意到,向循环添加Thread.Sleep(1000) (1秒)确实会强制应用程序正确地标记线程,但我正在尝试开发一个快速的多线程应用程序,并且为每个线程添加1秒延迟的想法是令人沮丧的。
有人能给我一些关于为什么我看到这种行为的见解吗?
谢谢..。
相同的
发布于 2010-09-29 21:27:47
您需要向每个新线程传递一个全新的对象。目前,它们都获得了对主线程中同一对象的引用,即oTaskParameters
在将MyNumber设置为MyThreadInfo构造函数上的参数后,尝试这样做:
for (int i = 1; i <= 5; i++)
{
MyThreadInfo oTaskParameters = new MyThreadInfo(i);
objTaskParameters.MyGuid = Guid.NewGuid();
ThreadPool.QueueUserWorkItem(new WaitCallback(objTask.ProcessDataForNTime), objTaskParameters);
}
MyThreadInfo(int i) : MyNumber(i)
{
// rest of construction logic
}这一更改意味着每个新线程都会获得一个不相交的MyThreadInfo实例,并相应地设置该线程的id。
仍然不能保证线程会以升序打印出它们的in。您必须引入某种类型的FIFO队列/处理来强制执行该操作。ordering of thread execution using Threadpool.QueueUserWorkItem对这个问题进行了详细的讨论。
https://stackoverflow.com/questions/3822015
复制相似问题