C# 处理列表中的项目<;对象>;通过一组线程-线程池 public void多线程() { List objectlist=新列表{ //假设它有大约10个对象 }; foreach(objectlist中的var obj) { 过程(obj); } } 专用作废处理(对象obj) { //实施 }

C# 处理列表中的项目<;对象>;通过一组线程-线程池 public void多线程() { List objectlist=新列表{ //假设它有大约10个对象 }; foreach(objectlist中的var obj) { 过程(obj); } } 专用作废处理(对象obj) { //实施 },c#,.net,multithreading,asp.net-core,asp.net-web-api,C#,.net,Multithreading,Asp.net Core,Asp.net Web Api,我正在尝试实现多线程,其中每个线程获取一个对象并处理它。。。我尝试创建5个单独的线程,每个线程处理2个对象…但这更像是硬条件…有没有办法使用线程池实现它…我会避免手动创建线程对象。现代.NET提供了更强大的工具来处理并发性。根据经验,每次在现代.NET中编写类似于new Thread的代码时,几乎可以肯定没有做正确的事情 似乎最适合您的问题的解决方案是在Parallel类上定义的静态方法ForEach Parallel.ForEach基本上会在提供的对象序列上运行一个并行的ForEach循环。用

我正在尝试实现多线程,其中每个线程获取一个对象并处理它。。。我尝试创建5个单独的线程,每个线程处理2个对象…但这更像是硬条件…有没有办法使用线程池实现它…

我会避免手动创建
线程
对象。现代.NET提供了更强大的工具来处理并发性。根据经验,每次在现代.NET中编写类似于
new Thread
的代码时,几乎可以肯定没有做正确的事情

似乎最适合您的问题的解决方案是在
Parallel
类上定义的静态方法
ForEach

Parallel.ForEach
基本上会在提供的对象序列上运行一个并行的
ForEach
循环。用于并行处理项目的线程从.NET framework直接管理的线程池中借用,因此您无需自己创建
thread
对象

<> P>有一些注意事项,在继续之前需要考虑:

  • 所提供序列中的项目必须是独立的,以便并行处理它们是安全的操作
  • 当处理所提供序列的每个项所完成的工作负载是CPU限制的时,使用
    Parallel.ForEach
    是有意义的。对于I/O工作负载,方法必须不同(在这种情况下,您可以使用
    Task.whalll
  • 数据并行不是免费的,在进行并行处理时总是有计算成本的<因此,您需要考虑权衡,并始终测量代码的性能。一般来说,当处理每个项目所做的工作并不琐碎,并且在多核处理器上运行代码时,数据并行性是有益的。在某些情况下,经典的顺序
    foreach
    循环完全有可能带来更好的性能
也就是说,下面是一个代码示例:

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
}
公共静态类程序
{
公共静态void Main(字符串[]args)
{
列表项=…//为简洁起见省略了代码
ProcessItemsInParallel(项目);
}
私有静态void ProcessItemsInParallel(IEnumerable items)
{
Parallel.ForEach(items,ProcessItem);
}
私有静态void ProcessItem(对象项)
{
//一些非琐碎的CPU限制的工作在这里完成。。。
}
}
这种方法称为数据并行。考虑阅读./p>的文档。 以下是一些关于.NET中并发主题的重要阅读资料:

  • 约瑟夫·阿尔巴哈里写的,这是一本免费电子书。这本书有点老,但为了掌握基本知识,值得一读。这仍然是一本很棒的书
  • 关于C#中并发性的讨论。在我看来,如果你是一名.NET开发人员并且想学习处理并发性的现代模式,那么这本书就是你需要阅读的
  • 这是另一个伟大的资源,充满了有用和有趣的文章
最后的考虑

我注意到您在问题中使用了ASP.NET核心标记。您没有提到要在何处执行大量CPU限制的处理

如果您想在处理HTTP请求的上下文中(我是指在某个控制器的操作方法中)进行这种处理,我强烈建议您不要这样做。这样做会破坏服务器的可扩展性。

应在后端服务中执行大量CPU限制的处理;HTTP请求意味着能够快速得到服务

通过保持服务器的可伸缩性,可以在服务HTTP请求的上下文中更轻松地处理I/O绑定的工作负载。您可以使用异步操作方法来执行此操作。这并不能保证单个HTTP请求将得到快速服务(这取决于您将要执行的I/O工作的类型),但至少可以节省服务器的可伸缩性


但在服务HTTP请求时,请不要运行并行的foreach循环。使用队列将工作负载从web服务器转发到后端服务。

使用PLinq
objectlist.aspallel().ForAll(o=>{/*your stuff*/})或并行类
Parallel.ForEach(objectlist,o=>{/*你的东西*/})
。对于更复杂的场景,您可以使用TPL数据流库
过程
方法是什么样的工作负载?是吗?@TheodorZoulias CPU boundFor CPU绑定工作负载.Net平台提供的最容易使用的工具是类和并行LINQ()。
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...
  }
}