简体   繁体   English

处理列表中的项目<object>通过一组线程 - 线程池<div id="text_translate"><pre>public void multithread() { List&lt;Bbject&gt; objectlist= new List&lt;Object&gt;{ //consider it has around 10 objects }; foreach (var obj in objectlist) { Process(obj); } } private void process(Object obj) { //Implementation }</pre><p> 我正在尝试实现多线程,其中每个线程采用 object 并对其进行处理...我尝试创建 5 个单独的线程,其中每个线程处理 2 个对象...但它更像是硬配置...有什么方法可以使用它来实现它线程池...</p></div></object>

[英]Process items in list<Object> by a set of threads - threadpooling

public void multithread()
{

  List<Bbject> objectlist= new List<Object>{
      //consider it has around 10 objects
   };
  foreach (var obj in objectlist)
  {               
      Process(obj);
   }
}

private void process(Object obj)
{
    //Implementation
}

I am trying to achieve multithreading where each thread takes a object and process it... i tried creating 5 seperate threads where each thread process 2 objects...but it was more like hardconding...is there any way to achieve it using threadpool...我正在尝试实现多线程,其中每个线程采用 object 并对其进行处理...我尝试创建 5 个单独的线程,其中每个线程处理 2 个对象...但它更像是硬配置...有什么方法可以使用它来实现它线程池...

I would avoid to create Thread objects manually.我会避免手动创建Thread对象。 Modern .NET offers more powerful tools to handle concurrency.现代 .NET 提供了更强大的工具来处理并发。 As a rule of thumb each time you write code like new Thread in modern .NET you are almost certainly not doing the right thing.根据经验,每次您在现代 .NET 中编写new Thread之类的代码时,您几乎肯定没有做正确的事情。

The solution which seems to suit the best for your problem is the static method ForEach defined on the Parallel class.似乎最适合您的问题的解决方案是在Parallel class 上定义的 static 方法ForEach

Parallel.ForEach will basically run a parallel foreach loop on a provided sequence of objects. Parallel.ForEach基本上将在提供的对象序列上运行并行foreach循环。 The threads used to process the items in parallel are borrowed from the thread pool which is managed directly by the .NET framework, so that you don't need to create Thread objects by yourself.用于并行处理项目的线程是从由.NET框架直接管理的线程池借用的,因此您不需要自己创建Thread对象。

There are some caveats that you need to consider before proceed:在继续之前,您需要考虑一些注意事项:

  • the items in the provided sequence must be independent so that processing them in parallel is a safe operation提供的序列中的项目必须是独立的,以便并行处理它们是安全的操作
  • using Parallel.ForEach makes sense when the workload done to process each item of the provided sequence is CPU-bound.当处理所提供序列的每个项目的工作负载受 CPU 限制时,使用Parallel.ForEach是有意义的。 For I/O workload the approach must be different (in that case you can use Task.WhenAll for instance)对于 I/O 工作负载,方法必须不同(在这种情况下,您可以使用Task.WhenAll例如)
  • data parallelism does not come for free, there is always a computational cost in doing parallel processing.数据并行不是免费的,并行处理总是有计算成本。 So you need to consider the trade-off and always measure the performance of your code .因此,您需要考虑权衡并始终衡量代码的性能 Generally speaking data parallelism is beneficial when the work done to process each item is not trivial and you run your code on a multi-core processor.一般来说,当处理每个项目的工作不是微不足道的并且您在多核处理器上运行代码时,数据并行性是有益的。 It is totally possible that a classic sequential foreach loop leads to better performance in some cases.在某些情况下,经典的顺序foreach循环完全有可能带来更好的性能。

That said, here is a code sample:也就是说,这是一个代码示例:

public static class Program 
{
  public static void Main(string[] args) 
  {
    List<object> items = ... // code omitted for brevity

    ProcessItemsInParallel(items);
  }

  private static void ProcessItemsInParallel(IEnumerable<object> items) 
  {
    Parallel.ForEach(items, ProcessItem);
  }
   
  private static void ProcessItem(object item) 
  {
    // some non - trivial CPU bound work is done here...
  }
}

This approach is known as data parallelism.这种方法称为数据并行。 Consider reading the documentation for Parallel.ForEach .考虑阅读Parallel.ForEach的文档。

Here are some great readings on the subject of concurrency in .NET:以下是关于 .NET 中并发主题的一些精彩读物:

  • Threading in C# by Joseph Albahari which is a free ebook. Joseph Albahari的 C# 中的线程,这是一本免费的电子书。 This book is a bit older, but it is worth reading it in order to gain the basics.这本书有点老,但为了获得基础知识,值得一读。 It is still a great reading.这仍然是一本很棒的读物。
  • the Stephen Cleary book about concurrency in C#. Stephen Cleary 关于并发的书C#。 In my opinion this is the book that you need to read if you are a .NET developer and you want to learn modern patterns to handle concurrency.在我看来,如果您是 .NET 开发人员并且想要学习处理并发的现代模式,那么您需要阅读本书。
  • the Stephen Cleary blog is another great resource, full of useful and interesting articles. Stephen Cleary 博客是另一个很好的资源,里面充满了有用和有趣的文章。

A final consideration.最后的考虑。

I noticed that you have used the ASP.NET core tag for your question.我注意到您在问题中使用了 ASP.NET 核心标签。 You did not mention where you are trying to perform your heavy CPU-bound processing.您没有提到您尝试在哪里执行繁重的 CPU 密集型处理。

If you are thinking to do this kind of processing in the context of handling an HTTP request (I mean inside an action method of some controller) I strongly advise against it.如果您想在处理 HTTP 请求的上下文中进行这种处理(我的意思是在某个控制器的操作方法中),我强烈建议您不要这样做。 Doing so wil kill the scalability of your server.这样做会破坏服务器的可扩展性。

Heavy CPU-bound processing should be performed in backend services;应在后端服务中执行繁重的 CPU 密集型处理; HTTP requests are meant to be served quickly. HTTP 请求旨在快速提供服务。

I/O bound workload can be more easily handled in the context of serving HTTP requests by preserving server scalability.通过保留服务器的可扩展性,在为 HTTP 请求提供服务的上下文中,可以更轻松地处理 I/O 绑定工作负载。 You can do so by using asynchronous action methods .您可以通过使用异步操作方法来做到这一点。 This won't guarantee that the single HTTP request will be served quickly (that depends on the type of I/O work that you are going to do), but at least you will save the scalability of your server.这不能保证单个 HTTP 请求将得到快速处理(这取决于您将要执行的 I/O 工作的类型),但至少您将节省服务器的可伸缩性。

But please do not run a parallel foreach loop when serving HTTP requests.但请不要在服务 HTTP 请求时运行并行foreach循环。 Use a queue to forward the workload from your web server to a backend service instead.使用队列将工作负载从 web 服务器转发到后端服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM