【问题标题】:Use ThreadPool or Thread使用线程池或线程
【发布时间】:2011-11-23 01:55:07
【问题描述】:

我有 1 个集合,我正在将内容保存到持久存储中。然后我最终得到了 3 个我喜欢保存到持久存储中的集合。

起初我使用 ThreadPool 来保存一个集合,但现在我有 3 个集合。由于每个集合都进入不同的存储,我不想将它们组合或保存到同一个地方。

我的问题是我应该使用手动线程并为每个 Save() 方法创建一个线程,还是应该为每个方法创建 3 个线程池,还是应该在一个 ThreadPool.QueueUserWorkItem 调用中调用所有 3 个方法。

1.第一种方法

ThreadPool.QueueUserWorkItem(o => 
             { Save<Foo>(ConcurrentCollectionStorage.Bus1);
               Save<Bar>(ConcurrentCollectionStorage.Bus2);
               Save<Car>(ConcurrentCollectionStorage.Bus3);
             });

2. 第二种方法

ThreadPool.QueueUserWorkItem(o =>
               { Save<Foo>ConcurrentCollectionStorage.Bus); });  
ThreadPool.QueueUserWorkItem(o =>
               { Save<Bar>(ConcurrentCollectionStorage.Bus2); });  
ThreadPool.QueueUserWorkItem(o =>
               { Save<Car>(ConcurrentCollectionStorage.Bus3); });  

3. 第三种方法。手动创建线程并加入它们。

在执行这些操作时,我不希望我的应用程序挂起。我希望它处理和保存数据,完成,但不影响前台进程,整个应用程序。

最好的方法是什么?

我应该使用哪一个?有没有更好的方法来做到这一点?

【问题讨论】:

  • 线程可以为您购买更多的 CPU 周期,而不是更多的磁盘。目前尚不清楚这里的关键资源是什么,但很可能不是 cpu 周期。
  • 继续@Hans Passant,为什么要使用 3 个线程?您不能将所有 3 个集合都排队到一个线程吗?您可以将所需的目标服务器/文件夹/任何内容加载到每个项目中,以便线程知道将其放在哪里。
  • 嗯,是的,这不是很受 cpu 限制,但我希望它们在不影响应用程序的情况下发生,这就是为什么我想将它们作为线程池运行。你能想到什么更好的吗?

标签: c# .net multithreading concurrency threadpool


【解决方案1】:

使用 .NET 4.0,您可以使用任务并行库:

    Task.Factory.StartNew(() => { Save<Foo>(ConcurrentCollectionStorage.Bus1); });
    Task.Factory.StartNew(() => { Save<Bar>(ConcurrentCollectionStorage.Bus2); });
    Task.Factory.StartNew(() => { Save<Car>(ConcurrentCollectionStorage.Bus3); });

但是,您的问题并不清楚关键瓶颈是什么。如果您的瓶颈是磁盘 IO 或网络延迟,则 TPL 无法帮助您。

如果你想让你的主线程等待它们全部完成,你可以这样做(有几种方法可以做到):

    Task t1 = Task.Factory.StartNew(() => { Save<Foo>(ConcurrentCollectionStorage.Bus1); });
    Task t2 = Task.Factory.StartNew(() => { Save<Bar>(ConcurrentCollectionStorage.Bus2); });
    Task t3 = Task.Factory.StartNew(() => { Save<Car>(ConcurrentCollectionStorage.Bus3); });

    Task.WaitAll(t1,t2,t3);

这样,运行任务的线程将等待它们完成。 t1、t2 和 t3 将异步运行。

【讨论】:

  • 为什么你不在一个任务中调用 3 个方法,而是产生 3 个任务?
  • @user177883:这取决于你想做什么。如果需要,您可以在一项任务中将它们全部调用。就像我说的,这取决于你的瓶颈。如果 Save 操作阻塞,您不妨让它们在一个任务中运行。
  • 它们是异步运行的吗?他们会互相等待完成吗?
  • @user177883:它们异步运行。如果您希望它们从一个线程同步运行,您可以使用ContinueWith 方法。
  • 如果将它们包装在单个任务中,父任务,它们仍然运行异步吗?如果我把 parent.wait();他们跑到完成?
【解决方案2】:

如果您使用的是 .net 4,您应该使用 TASK 而不是调用 ThreadPool API。 如果您的保存操作很短,请按原样使用。如果它很长,这就是您考虑手动线程的原因,那么您应该使用任务但将其标记为“长时间运行”

HTH

【讨论】:

    【解决方案3】:

    由于每个集合都进入不同的存储,我不想将它们合并或保存到同一个地方。

    在执行这些操作时,我不希望我的应用程序挂起。我希望它处理和保存数据,完成,但不影响前台进程,整个应用程序。

    在线程池中排队三个线程。

    【讨论】:

    • 我需要在 threalpool 中加入 3 个线程吗?为什么我要在线程池中创建线程?
    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 2023-03-12
    • 2011-12-16
    • 2013-06-05
    • 2016-09-26
    相关资源
    最近更新 更多