首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ThreadPool参数

ThreadPool参数
EN

Stack Overflow用户
提问于 2010-09-29 21:25:34
回答 1查看 3.3K关注 0票数 0

在将一个简单的线程池解决方案放入我的应用程序之前,我正在测试它,但是我看到的结果对我来说没有任何意义。我有一个简单的表单,上面有一个按钮。此按钮启动以下循环:

代码语言:javascript
复制
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秒就结束了。

代码语言:javascript
复制
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);
    }
}

我希望结果在我的控制台/输出/调试日志中显示如下所示。当我浏览这个应用程序时,我确实看到了以下内容:

代码语言:javascript
复制
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...

但是,如果我全速运行应用程序,而不遍历代码或断点,它会输出以下内容:

代码语言:javascript
复制
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秒延迟的想法是令人沮丧的。

有人能给我一些关于为什么我看到这种行为的见解吗?

谢谢..。

相同的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-09-29 21:27:47

您需要向每个新线程传递一个全新的对象。目前,它们都获得了对主线程中同一对象的引用,即oTaskParameters

在将MyNumber设置为MyThreadInfo构造函数上的参数后,尝试这样做:

代码语言:javascript
复制
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对这个问题进行了详细的讨论。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3822015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档