重新启动正常线程

时间:2010-10-08 19:18:15

标签: c# .net multithreading visual-studio

让我们说我想要做的就是验证一百万个字符串,每次验证都需要几秒钟。

我的方法:

我有一个这样声明的线程数组:

Thread[] workers = new Thread[50];

我没有数组中的所有字符串,它们通过一些计算,然后我在启动进程时没有所有字符串,但我有一个方法返回下一个:

public string next()
{
  //my code
}

我已经能够像这样运行所有50个线程:

for (int x = 0; x < 50; x++)
{
workers[x] = new Thread(new ParameterizedThreadStart(myMethod));
workers[x].Start(next());
}

快速启动所有50个线程“同时”然后我的日志(由myMethod提供)几乎同时获得50个响应(1~1.5秒)

如何考虑到Thread类没有暴露任何事件或任何类似事件,如何让每个刚刚完成的线程再次使用下一个字符串运行?

注意:我已经完成了一些性能测试,我更喜欢使用常规线程而不是BackgroundWorkers。

在.net 3.5中使用C#。

4 个答案:

答案 0 :(得分:5)

听起来你应该使用ThreadPool。然后你可以这样做:

while(MoreWorkIsAvailable)
{
    string nextString = next();
    ThreadPool.QueueUserWorkItem(new WaitCallback(myMethod), nextString);
}

线程池甚至允许您在最大线程数上设置一个硬帽,以允许通过SetMaxThreads一次运行。

答案 1 :(得分:2)

您无法通过线程系统获取事件。您可以等待Thread.Join的单个线程,但是您不能等待任何线程并获得首先完成的线程。最好的方法是在每个线程中放置一个while循环来轮询工作项队列,直到队列为空。

答案 2 :(得分:1)

您可以像ADO.NET或枚举一样使用next()方法。保持返回值直到它完成,然后返回null。让你的线程在while循环中使用该方法,直到方法返回null,然后退出。

为了澄清,你需要做一些背景工作。你必须使你的next()方法是线程安全的,所以你总是返回下一个没有重复的值。您还必须将引用传递给对象而不是next()方法的输出。线程安全部分是关于它的唯一真正复杂的事情,它只是意味着你必须锁定next()方法的一部分:

  • 确定要使用的下一个字符串值
  • 并更新任何对象状态

状态稳定后,您可以释放锁定,下一个线程可以使其字符串工作。

编辑:这可能仍然是要走的路,尽管为了简单起见我喜欢ThreadPool方法。在这种情况下,代码将类似于:

YourStringGenerator generator;
//instatiate generator
for (int x = 0; x < 50; x++) 
{ 
    workers[x] = new Thread(new ParameterizedThreadStart(myMethod)); 
    workers[x].Start(generator); 
}

然后

myMethod(YourStringGenerator generator)
{
    String compare;
    while((compare=generator.next())!=null)
    {
        //do comparison, etc.
    }
    return;
}

next()看起来像

String next()
{
    lock(this.index)  //see msdn for info.  Link below.
    {
        //determine next string
        //update index
    }
    //generate or get next string from list and return it
    //or if empty, return null
}

see msdn for info

答案 3 :(得分:1)

添加到您的线程方法,不仅处理一个数据,而且处理“下一个无人认领”的数据。

您希望围绕枚举器的MoveNext进行一些同步,并获取对Current的引用的副本。没有两个线程可以推进枚举器并同时抓取项目。然后,在获得引用后,释放同步锁并进行验证。

您可能还想查看Microsoft的Px并行扩展以利用多个CPU(内核?)。我没有使用它,但如果你的验证是纯粹的算法(而不是对数据库进行检查),那么多处理器参与是击败单线程模型的唯一方法。