使用线程池还是线程?

4

我曾经有一个集合,我将内容保存到了持久存储中。现在我想要将三个集合保存到持久存储中。

一开始我使用线程池保存一个集合,但现在有三个集合需要保存,而且每个集合都要保存到不同的位置,所以我不想将它们合并或保存到同一个位置。

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

1.第一种方法

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

第二种方法

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

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

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

最好的方法是什么?

我应该使用哪一个?有更好的方法吗?


1
线程可以为您提供更多的CPU周期,而不是更多的磁盘。目前尚不清楚此处的关键资源是什么,但很可能不是CPU周期。 - Hans Passant
继@Hans Passant之后,为什么你想要使用3个线程呢?难道你不能将这3个集合都排队给一个线程吗?你可以在每个项目中加载所需的目标服务器/文件夹/等等,这样线程就知道该把它放在哪里了。 - Martin James
嗯,是的,这不是非常占用 CPU 的,但我希望它们在不影响应用程序的情况下发生,这就是为什么我想将它们作为线程池运行。你有更好的建议吗? - DarthVader
3个回答

3

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

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

将三个线程排队到线程池中。


我需要在线程池中加入3个线程吗?为什么要在线程池中创建线程? - DarthVader

2

在.NET 4.0中,您可以使用任务并行库(Task Parallel Library):

    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个任务? - DarthVader
@user177883:这取决于你想做什么。如果你愿意,你可以在一个任务中调用它们所有。就像我说的,这取决于你的瓶颈。如果Save<T>操作会阻塞,那么你最好让它们在一个任务中运行。 - Bryan Crosby
它们是否异步运行?它们是否等待彼此完成? - DarthVader
@user177883:它们以异步方式运行。如果您希望它们在一个线程中同步运行,可以使用ContinueWith方法。 - Bryan Crosby
如果将它们包装在一个单独的任务、父任务中,它们仍然会异步运行吗?如果我加上parent.wait(),它们会一直运行直到完成吗? - DarthVader
@user177883:我更新了我的答案,并添加了另一个示例。 - Bryan Crosby

1

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

希望对您有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接