代码之家  ›  专栏  ›  技术社区  ›  BlackMatrix

与许多独立线程同步

  •  1
  • BlackMatrix  · 技术社区  · 11 年前

    我的应用程序同时运行大量线程。完成后,他们必须(随机)睡一段时间,然后重新开始。

    如何用更少的资源重新启动它们?我不想在休眠时将所有线程都保存在RAM中,因为线程的数量非常庞大。 另一个毫无意义的解决方案是让每个线程都有自己的计时器。

    有什么最佳实践可以解决我的问题吗?

    2 回复  |  直到 11 年前
        1
  •  3
  •   Nate C-K    11 年前

    您可能需要研究线程池。这意味着你要启动少量的线程,然后让它们保持活动状态,让每个线程一个接一个地执行多个任务。通常,他们会从共享队列中删除作业。

    .NET平台对线程池有一些内置支持。

    下面是一篇MSDN文章,描述了线程池的一种方法:

    http://msdn.microsoft.com/en-us/library/3dasc8as.aspx

        2
  •  1
  •   Community CDub    7 年前

    除非您需要用于UI控件或遗留COM对象的STA线程,否则我不会直接创建任何线程并使用 Task.Run Task.TaskFactory.StartNew 相反有关更多信息,请查看任务并行库(TPL)标记wiki:

    https://stackoverflow.com/tags/task-parallel-library/info

    更新以解决对问题的评论:

    否,任务完成后,应在一段时间后重新启动 (随机)。他们应该一次又一次地做同样的工作,只需要 重新启动之间的超时。任务。运行(()=>而(true){DoWork(); Thread.Sleep(_random.Next(x,y)}是错误的做法

    使用 Thread.Sleep 这确实是一种糟糕的做法,尤其是在池线程上。它可能只对测试有用。使用异步lambda和 Task.Delay 而是:

    var task = Task.Run(async() => 
    {
        while (true) 
        {
            token.ThrowIfCanncellationRequested();
    
            DoPeriodicWork();
    
            await Task.Delay(1000);
        }
    }, token);
    

    您不会以这种方式阻塞一个池线程,它将返回到一个池,代码将在 await (或者甚至可能在同一个线程上,但当然你不应该指望这一点)。

    注意,将为创建嵌套任务 async lambda,其中 任务.运行 将自动展开 Task.Unwrap 。更多信息请参见Stephen Toub的博客文章: Task.Run vs Task.Factory.StartNew .