【发布时间】:2011-09-17 20:39:54
【问题描述】:
我的代码中有一个奇怪的错误。这是极其罕见的(可能每隔几周发生一次),但它就在那里,我不知道为什么。
我们有 2 个线程在运行,1 个线程获取网络消息并将它们添加到队列中,如下所示:
DataMessages.Enqueue(new DataMessage(client, msg));
另一个线程从这个队列中取出消息并处理它们,如下所示:
while (NetworkingClient.DataMessages.Count > 0)
{
DataMessage message = NetworkingClient.DataMessages.Dequeue();
switch (message.messageType)
{
...
}
}
但是,我经常在 switch (message.messageType) 行上收到 NullReferenceException,我可以在调试器中看到该消息为空。
不可能将空值放入队列(参见代码的第一部分),这是唯一使用队列的两件事。
队列不是线程安全的吗,是不是我在另一个线程入队的确切时刻出队,这导致了故障?
【问题讨论】:
-
.NET BCL 中很少有东西以这种方式是线程安全的。在这种情况下,“为了保证 Queue 的线程安全,所有操作都必须通过Synchronized 方法返回的包装器来完成”。如果适用,您的问题也可能是两个线程同时入队或出队。无论哪种方式,线程安全都是您的责任。
-
+1,好问题,它确实展示了竞争条件及其结果(损坏/不稳定/意外情况)。
-
从您的代码看来,您似乎只是在为您的线程做一个简单的循环。您应该考虑实施适当的bounded-buffer 来同步它。
标签: c# .net multithreading queue