【问题标题】:Dictionary in MultiThreaded Application (memory management?)多线程应用程序中的字典(内存管理?)
【发布时间】:2014-03-15 00:06:00
【问题描述】:

我有一个字典,它是Dictionary<int, RSendPacket> _Packets,并且有两个主线程。线程 #1 使用此函数添加数据包

public void EnqueueOutgoingData(int id, byte[] data)
{
    RSendPacket packet = new RSendPacket(data);
    _Packets.Add(id, packet);
}

线程#2 像这样通过套接字读取和发送数据包

private void _Process(RSendPacket packet)
{
    foreach (KeyValuePair<int, RSendPacket> o in _Packets)
    {
        //Socket send (o.Value >> That's RSendPacket class)
    }
}

此时,我遇到了一个错误。我正在添加“asdf”,但它带有“► o”。我认为这是一个线程/内存错误,但我无法修复它,因为我不知道如何解决!有人可以帮我解决这个问题吗? (我可以用 C++ 实现一个带有指针和内存管理的系统,这应该是一个内存管理问题 - 由我糟糕的 c# 引起)

EDIT1: 是的,没有线程安全的实现,但我已经用 'lock()' 尝试过,但不起作用!

EDIT2:哦,另一个重要的编辑。我在 Unity 中使用 C# 2.0。所以解决方案应该是 C# 2.0 (mono) 代码:/

【问题讨论】:

  • 您在哪里看到“损坏”的值?在_Process 方法中?如果您只排队和处理一个数据包,那行得通吗? (我认为这将在确定损坏原因时排除多线程问题。)
  • 另外,什么时候从_Packets 集合中删除发送的数据包? ...并且传递给_Processpacket 有什么意义吗?

标签: c# multithreading pointers memory-management dictionary


【解决方案1】:

看起来您可能想为这种操作使用队列,它更适合您尝试做的事情。

如果遇到并发问题,可以使用 ConcurrentQueue 类。

【讨论】:

  • 它必须是字典,因为我需要使用 id 键找到我的值。
  • 在您的示例中,您正在遍历 keyValuePairs 并仅发送值 - 请使用有关您如何使用字典的相关详细信息更新您的代码以获得更好的建议!
【解决方案2】:

您不必使用锁来保证线程安全。只需使用ConcurrentDictionary 代替常规字典即可。

【讨论】:

  • 它可以工作,但这不是我正在寻找的解决方案,因为 C# 2.0 :)
【解决方案3】:

Dictionary&lt;TKey, TValue&gt; 不是线程安全的,因此在您的多线程示例中行为未定义。此外,在迭代 Dictionary&lt;TKey, TValue&gt; 时返回项目的顺序是未定义的,因此即使您使用 ConcurrentDictionary&lt;TKey, TValue&gt; 或实现自己的锁定,您也可能无法获得预期的结果。

【讨论】:

    【解决方案4】:

    真正的解决方案(我已经尝试过并且可行)是l3arnon's answer,但我将在 C# 2.0 中实现这个系统,我已经像 this methodMonitor 一样实现了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2011-08-29
      相关资源
      最近更新 更多