Array.Resize(..)线程安全吗?

时间:2014-05-01 16:20:34

标签: c#

在一个用作SAEA线程安全缓冲区的数组上调用Array.Resize?不同的线程都写入它们自己分配的数组部分,我只想在连接用户增加时初始化大小耗尽后使数组更大而不锁定。

byte[] buffer; //Accessed
object expand_Lock = new object();

public void AsyncAccept()
{
    //Lock here so we don't resize the buffer twice at once
    lock(expand_Lock)
    {
        if (bufferFull)
        {
            Array.Resize(buffer, buffer.Length + 2048 * 100); //Add space for 100 more args
            //Is Array.Resize threadsafe if buffer can be read/wrote to at anytime?
            AssignMoreSAEA(2048, 100); //irrelevant to question what this does
        }
    }
}

2 个答案:

答案 0 :(得分:3)

不,Array.Resize不是线程安全的。正在调整大小的数组可能必须在内存中移动,调整大小的数组甚至不会与传入的数组相同。

这意味着一个线程可能正在写入原始数组,而Array.Resize正在创建新数组并复制项目 - 复制操作不受保护。这可能会导致数据丢失。

答案 1 :(得分:2)

  • 该方法不会改变原始数组。
  • 该方法不会在多线程场景中抛出异常,因为源阵列具有固定大小且元素未被解除引用,因此不会在单线程场景中抛出异常。
  • 如果新长度等于旧长度,则该方法是线程安全的,因为根据文档,该方法在这种情况下不执行任何操作。
  • 如果在操作期间修改了源数组,则未指定调整大小的数组的内容。如果数组的元素适合机器字(IntPtr.Size或更小,包括引用类型),则在调用方法时,结果数组的元素将包含源数组中相同元素的值。 ,或在执行调整大小操作期间分配给该元素的任何值。如果元素不适合机器字,那么在执行调整大小操作期间修改的任何元素都将导致调整大小的数组中相应元素的未指定值。