c# - 两个线程使用相同的变量,会产生问题

标签 c# multithreading sockets c#-4.0

我有一个列表和两个使用该列表的线程。

第一个线程获取新连接,每个新连接都添加到列表中。

第二个线程在List上循环以处理连接(使用foreach)。

问题在于,有时当第二个线程在列表上循环时,列表​​会在循环结束之前更改。我什至尝试创建列表的新副本并遍历它。但是,这还会产生其他一些问题。

我不想创建一个新线程来处理每个新连接,因为我知道太多线程会影响性能。还有其他方法可以处理连接吗?

最佳答案

2个问题。

1)您需要锁定列表。
您需要确保您具有对该列表的互斥访问权限,因此在对其进行修改时不能一一列举。
第一种解决方案是使用锁:

class Mailbox {
    List<int> list;

    void Send(int a) {
         lock(list) {
              list.Add(a);
         }
     }

     int Receive() {
         lock(list) {
             // Enumerate
             return ...;
         }
      }
}

更优雅的是,您可以使用Concurrent命名空间中的新集合之一,例如BlockingCollection。后者不是枚举安全的,但是提供了Take()方法,可在生产者插入对象时使用该方法从对象中检索对象。

2)避免创建大量的线程。
您可以使用.NET thread pool来排队尽可能多的请求,并且框架将负责将它们映射到实际线程上,而不会杀死系统。

关于c# - 两个线程使用相同的变量,会产生问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3219168/

相关文章:

c# - 创建一个匿名对象,如何使用循环添加项目

c# - 使用 Go 编码 UTF-8

multithreading - 当事件模式不适用时,线程应该休眠多长时间?

c++ - 如何在 C++ 的新线程中访问类中的数据?

java - 小消息的套接字缓冲区大小

c# - 确定 double 是否不为零的最佳方法是什么

C# winform,如何使轨迹条随着声音文件移动(增加其值)?

c - 如何在所有端口上绑定(bind)()?

java - "subsequent read"在 volatile 变量的上下文中意味着什么?

linux - 在 IO-Socket-IP/t/04local_client_v6.t 上安装 perl 5.20.3 失败