C# 队列上的竞争条件
下面的代码处理带有2个参数的套接字消息。它将信息放入队列并在另一个线程上处理。我的问题是,如果两条消息紧跟在另一条消息之后进入队列并发送到方法ProcessData,ProcessData上是否存在竞争条件C# 队列上的竞争条件,c#,.net,multithreading,c#-4.0,race-condition,C#,.net,Multithreading,C# 4.0,Race Condition,下面的代码处理带有2个参数的套接字消息。它将信息放入队列并在另一个线程上处理。我的问题是,如果两条消息紧跟在另一条消息之后进入队列并发送到方法ProcessData,ProcessData上是否存在竞争条件 private void DataIn(long Code, string Message) { if (!Started) { if (DataInQueue == null) DataInQueue = new Queue(); DataInThrea
private void DataIn(long Code, string Message)
{
if (!Started)
{
if (DataInQueue == null)
DataInQueue = new Queue();
DataInThread = new Thread(new ThreadStart(ThreadProcedure));
DataInThreadEnding = false;
DataInThread.IsBackground = true;
DataInThread.Start();
Started = true;
}
DataInQueue.Enqueue(new cDataIn(Code, Message));
}
private void ThreadProcedure()
{
while (!ProgramEnding)
{
Queue mySyncdQ = Queue.Synchronized(DataInQueue);
if (mySyncdQ != null && mySyncdQ.Count > 0)
{
cDataIn data = null;
// Creates a synchronized wrapper around the Queue.
if (mySyncdQ.Count > 0)
data = (cDataIn)mySyncdQ.Dequeue();
ProcessData(data);
}
}
}
更新
在您的代码中,队列未以线程安全的方式使用。。。您显示的代码不足以确定是否存在竞争条件,但使用ConcurrentQueue
您可以获得更好的性能。。。在ThreadProcedure中,您可以使用null调用ProcessData,就我所知,为了安全起见,ProcessData应该是可重入的,所有这些都可以工作
使用-可以避免一些可能的问题。。。并查看为线程安全生产者/消费者场景设计的。。。这两种方法都可以无锁工作,而且速度非常快 更新
在您的代码中,队列未以线程安全的方式使用。。。您显示的代码不足以确定是否存在竞争条件,但使用ConcurrentQueue
您可以获得更好的性能。。。在ThreadProcedure中,您可以使用null调用ProcessData,就我所知,为了安全起见,ProcessData应该是可重入的,所有这些都可以工作
使用-可以避免一些可能的问题。。。并查看为线程安全生产者/消费者场景设计的。。。这两种方法都可以无锁工作,而且速度非常快 是的,我认为这甚至会使您的队列处于不稳定状态。您应该使用.NET4附带的。它的线程安全的开箱即用和优化
向Gert Jan致意是的,我认为这甚至会使您的队列处于不稳定状态。您应该使用.NET4附带的。它的线程安全的开箱即用和优化
关于Gert Jan,您的代码不是线程安全的。请注意: 为了保证
队列的线程安全
,所有操作必须仅通过此包装器完成
您直接使用队列,因此代码不是线程安全的。要解决此问题,请始终使用返回的包装器,如文档所述
或者,如果您在.Net 4下,请使用ConcurrentQueue
如果您想在早期版本的.Net上使用通用队列,您可以使用
队列
,并始终在锁中访问它
您的代码不是线程安全的。请注意:
为了保证队列的线程安全
,所有操作必须仅通过此包装器完成
您直接使用队列,因此代码不是线程安全的。要解决此问题,请始终使用返回的包装器,如文档所述
或者,如果您在.Net 4下,请使用ConcurrentQueue
如果您想在早期版本的.Net上使用通用队列,您可以使用
队列
,并始终在锁中访问它
您是说有问题吗?队列类的文档()底部有一段关于线程安全的内容,说明实例成员不是TS。我还没有查看实现,看看会发生什么,但是您可以通过旋转两个线程来检查自己。一个泵入顺序消息(1,2,3,…),另一个读取它们。您可能会得到一个异常或间隙/双精度(1,2,2,4,5,…)+1对于BlockingCollection,这是jon描述的P-C场景中使用的类。您是说有问题吗?队列类的文档()底部有一段关于线程安全的内容,说明实例成员不是TS。我还没有查看实现,看看会发生什么,但是您可以通过旋转两个线程来检查自己。一个泵入顺序消息(1,2,3,…),另一个读取它们。您可能会得到一个异常或间隙/双精度(1,2,2,4,5,…)+1对于BlockingCollection,这是在jon描述的P-C场景中使用的类。您为什么说队列有问题?我更担心ProcessData会很快被连续调用,第二个线程可能会超过第二个线程first@Jon,内存泄漏很可能不会影响你。你可以自己做一个测试台,就像我在Yahia的回答中建议的那样。这取决于队列的内部实现。它可能会在引擎盖下使用一个需要复制的数组,当您同时复制两次时,可能会使其处于不满意的状态。我不会;Don’别冒这个险1.你为什么说排队有问题?我更担心ProcessData会很快被连续调用,第二个线程可能会超过第二个线程first@Jon,内存泄漏很可能不会影响你。你可以自己做一个测试台,就像我在Yahia的回答中建议的那样。这取决于队列的内部实现。它可能会在引擎盖下使用一个需要复制的数组,当您同时复制两次时,可能会使其处于不满意的状态。我不会;不要冒险..所以我需要在排队和退队时调用synchronize?这就是文档中所说的,不是吗?实际上没有说排队和退队Genqueue和退队是操作,所以它确实是这样说的。所以我需要在排队和退队时调用synchronize?这就是文档中所说的,不是吗?实际上并没有说排队和退队排队和退队都是操作,所以它确实是这样说的。