【问题标题】:C# System.ArgumentException: Destination array was not long enoughC# System.ArgumentException:目标数组不够长
【发布时间】:2013-11-05 08:37:59
【问题描述】:

我有一个由 SerialPort.DataReceived 方法提供的通用 Queue 对象。

调用 ToArray() 方法时,有时会出现异常“目标数组不够长”。代码:

        byte[] tmpArray;

        try
        {
            tmpArray = queue.ToArray();
        }
        catch (Exception ex) 
        {

记录一下:queue.Count 永远不会超过 500。

虽然这很可能是线程问题,但我不明白异常。队列的 ToArray() 方法中的目标数组何时会太短?

如果这是一个线程问题,那么将数据从 SerialPort 获取到队列时的最佳做法是什么?

顺便说一句:我在写之前锁定队列。也许我也应该在 ToArray() 之前锁定它?

【问题讨论】:

  • 在使用队列的任何地方都需要一个锁。 EnqueueDequeueToArray 等。考虑使用线程安全集合
  • 你是如何实现数据接收处理程序的?
  • 锁解决了这个问题。使用线程安全集合 (ConcurrentQueue) 重写的工作量太大。 ;-)
  • CloudyMarble:SerialPort.DataReceived 事件。在事件处理程序中检查 BytesToRead 是否大于 null。我使用 SerialPort.Read 方法将数据读入临时字节数组。然后入队。写之前当然要锁定Queue对象。

标签: c# thread-safety serial-port queue


【解决方案1】:

我想回答我自己的问题,或者至少对奇怪的异常消息给出一个假设。

这更像是对异常消息的一个问题,以及为什么框架告诉我一个数组太小,即使创建该数组不是我的责任。

由于这很可能是与线程相关的问题,因此 Queue.ToArray() 可以抛出“目标数组不够长”的异常的唯一方法是当队列本身在另一个线程中增长而 ToArray 尝试复制它时..

ToArray 方法为我们提供了一个新数组。因此,必须首先分配该数组,然后将数据从队列复制到数组。正如我所说,SerialPort.DataReceived 事件处理程序负责将元素添加到队列中。如果在分配数组后立即触发 SerialPort.DataReceived 事件,则队列将大于数组。

框架可能很难或不可能检测到这一点。

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 2012-05-08
    • 2020-09-21
    • 2017-06-20
    • 2014-05-11
    • 2016-04-08
    • 2022-01-23
    • 1970-01-01
    • 2019-09-12
    相关资源
    最近更新 更多