如何存储在线程池中运行的任务的结果?

时间:2016-11-22 22:03:08

标签: c# .net multithreading task-parallel-library threadpool

我遇到了线程池效率问题。我不确定我是否了解整个概念。在问这个问题之前我做了很多阅读,我知道如果你有很多小的,相对较快的函数以及更重要的 - 非阻塞任务,那么线程池是一个很好的解决方案。在线程池中使用lock非常糟糕。

这是我的问题:如何从threadpool 函数返回值?如果你有函数来运行它们可能会产生一些结果,对吗?将这些结果存储在某处是件好事。 其中吗

我正在跑c.a.线程池中200k非常快的函数。我存储在List中的结果。当然,我必须这样做:

lock(lockobj)
{
    myList.Add(result);
}

那么,这是正确的方法吗?我的意思是,如果你的函数返回SOMETHING,你必须将它们存储在某种集合中。它必须是一个阻止集合。所以,我开始思考...... "阻塞在线程池中是非常重要的,但你必须这样做,至少一次 - 在每个函数结束时

如何存储/返回在线程池中运行的函数的结果?

谢谢! JB

编辑:通过 "功能" 我的意思是......

 ThreadPool.QueueUserWorkItem(state =>
 {
    Result r = function(); // previously named "Task"
    lock(lockobj)
    {
        allResults.Add(r);
    }
 }

2 个答案:

答案 0 :(得分:1)

如果您不想阻止ThreadPool线程,请使用无锁方法。当你将项目排队时,ConcurrentQueue目前是无锁的(从.NET 4.6.2开始)。

所以简单地这样做:

public static ConcurrentQueue<Result> AllResults { get; } = new ConcurrentQueue<Result>();

ThreadPool.QueueUserWorkItem(state =>
{
    Result r = function();
    AllResults.Enqueue(r);
}

这可以保证您不会阻止ThreadPool个帖子。

答案 1 :(得分:0)

线程安全/同步的任何类型的集合都将执行 。 .net框架中有很多。

您还可以使用 volatile 变量在多个线程之间存储数据 - 但这通常被视为不良做法

另一种方法可以是在可以产生结果的任务上安排这些操作,它们默认在线程池上运行,您可以通过等待方法并检查返回的任务的结果来获取返回值。 p>

最后,您可以编写自己的代码,以便使用 lock,semaphores,mutex等

等内容来同步对代码/变量等某些区域的访问。