gpt4 book ai didi

C#:为迭代正确锁定队列

转载 作者:行者123 更新时间:2023-12-03 23:19:35 24 4
gpt4 key购买 nike

我正在使用队列 (C#) 来存储必须发送到任何连接的客户端的数据。

我的锁语句是私有(private)只读的:

private readonly object completedATEQueueSynched = new object();

入队只有两个方法:

1) 由鼠标移动启动,由主线程执行:

public void handleEddingToolMouseMove(MouseEventArgs e)
{
AbstractTrafficElement de = new...
sendElementToAllPlayers(de)
lock (completedATEQueueSynched)
{
completedATEQueue.Enqueue(de);
}
}

2) 从按钮事件开始,也由 mainform 线程执行(这里无关紧要,但安全总比抱歉好):

public void handleBLC(EventArgs e)
{
AbstractTrafficElement de = new...
sendElementToAllPlayers(de);
lock (completedATEQueueSynched)
{
completedATEQueue.Enqueue(de);
}
}

此方法由负责连接的特定客户端的线程调用。这是:

private void sendSetData(TcpClient c)
{
NetworkStream clientStream = c.GetStream();
lock (completedATEQueueSynched)
{
foreach (AbstractTrafficElement ate in MainForm.completedATEQueue)
{
binaryF.Serialize(clientStream, ate);
}
}
}

如果客户端连接并且我同时移动鼠标,则会发生死锁。如果我只锁定迭代,则会抛出 InvalidOperation 执行,因为队列已更改。

我也尝试过同步 Queue-Wrapper,但它不适用于 Iterating。 (即使与锁组合)有任何想法吗?我只是没弄错

最佳答案

您可以减少争用,可能足以使其可接受:

private void sendSetData(TcpClient c)
{
IEnumerable<AbstractTrafficElement> list;

lock (completedATEQueueSynched)
{
list = MainForm.completedATEQueue.ToList(); // take a snapshot
}

NetworkStream clientStream = c.GetStream();
foreach (AbstractTrafficElement ate in list)
{
binaryF.Serialize(clientStream, ate);
}
}

当然,快照会引入它自己的时序逻辑。 “所有元素”在任何给定时刻的确切含义是什么?

关于C#:为迭代正确锁定队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11767858/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com