foreach循环中的多线程C#

Posted

技术标签:

【中文标题】foreach循环中的多线程C#【英文标题】:MultiThreading in foreach loop C# 【发布时间】:2021-06-01 17:35:55 【问题描述】:

我在c#中有一个常用的方法。

ReadfromSource 方法根据传递的配置参数执行不同的操作。

它执行类似的操作

    无休止地监听 TCP 端口并接收传入的数据。 无休止地监听一个 http 端口并接收传入的数据。 无休止地监听文件夹路径并接收传入的文件。
public void ReadData(List<Configuration> configurations)

   foreach(var config in configurations)
   
    ReadfromSource(Configuration config);
   

public void ReadfromSource(Configuration config)

       while(true)
       

        // code for reading data from tcp port

        thread.sleep(1000);      //listens for each and every second

        


使用多线程,我需要同时运行所有操作

如何在 c# 中使用多线程实现上述场景,在此先感谢。

【问题讨论】:

探索者异步等待 how to implement the above scenario using mutithreading in c#, Task.Run 可能是一个起点。 我在 foreach 循环中尝试了Task.Run,但是第一个任务是单独创建并启动的......剩余的任务没有创建 这是一个复杂的问题,“如何实现多线程?”没有直接的答案,这取决于很多事情,包括你的 ReadFromSource 实际做了什么。对于 I/O 绑定操作,您不应该使用 Task.Run,​​而是使用异步 I/O API,例如 Stream.ReadAsync 可以查看同样的问题:***.com/questions/9418554/… 【参考方案1】:

您可以使用Task.WhenAll() 并行运行多个任务。

public async Task ReadData(List<Configuration> configurations)

    var tasks = new List<Task>();

    foreach (var config in configurations)
    
        tasks.Add(ReadfromSource(config));
    

    await Task.WhenAll(tasks);


public async Task ReadfromSource(Configuration config)

    while (true)
    
        // code for reading data from tcp port
        await Task.Delay(1000);
    

【讨论】:

我想说的是,做 TCP I/O 的代码应该使用 TcpClient 的异步方法(或任何正在使用的 TCP 类),例如ReadAsync 而不是 Read 等等。因为 OP 在上面写过他尝试了 Task.Run,​​所以我想强调将 I/O 绑定的东西包装在 CPU 绑定的任务(Task.Run 是)中通常是一个坏主意,并且正确的 I/O 绑定任务(ReadAsync、WriteAsync)应该是首选。

以上是关于foreach循环中的多线程C#的主要内容,如果未能解决你的问题,请参考以下文章

如何使用foreach循环进入另一个foreach循环来遍历c​​odeigniter中的两个不同的数据表?

<c:foreach>怎么改变循环次数

Laravel 在不使用 foreach 循环的情况下发送单独的多封邮件

foreach循环

详细讲解foreach循环的用法

C ++中二维数组中的foreach循环