String.Concat和线程安全?

Roy*_*mir 0 .net c# string multithreading

在解决了这个问题之后,我仍然有一个问题.

我有两个优秀的答案,但我仍然有找到一个麻烦怎么会这样实际上是发生:(怎么可能有故障的情况可能会发生):

我将从一个例子开始:

public void Do(string [] g)
{
   g=null;     //<========
}

void Main()
{
    var t=new string[3];
    t[0]="1";   t[1]="1";   t[2]="1";
    Do( t);
    Console.WriteLine ( t.Length);
}
Run Code Online (Sandbox Code Playgroud)

标记行可以在不同的线程中执行,但每个线程都有自己的 g变量!
(请记住,我无法在arrray中添加项目.因为创建时会创建数组长度)

无论我对该函数 做什么Do- (无论在什么线程中),Console.Writeline结果将始终是3(除非使用ref).

所以让我们看看真正的代码:

    public static string Concat(params string[] values)
  #1  {
  #2      if (values == null)
  #3       {
  #4            throw new ArgumentNullException("values");
  #5       }
  #6        int totalLength = 0;
  #7        string[] strArray = new string[values.Length];
  #8        for (int i = 0; i < values.Length; i++)
  #9          {
  #10            string str = values[i];
  #11            strArray[i] = (str == null) ? Empty : str;
  #12            totalLength += strArray[i].Length;
  #13            if (totalLength < 0)
  #14            {
  #15                throw new OutOfMemoryException();
  #16            }
  #17         }
  #18        return ConcatArray(strArray, totalLength);
  #19   }
Run Code Online (Sandbox Code Playgroud)

我的意思是:一旦我在#1上,在线程中X,这个线程将永远具有长度为3的数组.

如果另一个线程想要销毁/更改数组长度(我不知道如何,因为数组具有固定的长度,他所能做的就是制作它null) - 它将有一个不同的指针地址副本.

我必须在这里遗漏一些东西.

  • 我错过了什么?

  • 什么是其他线程可以执行哪些会导致错误的代码?(假设我们不复制数组).

Avn*_*tan 6

我在最初的帖子中找到了Jon Skeet和Eric Lippert的答案,我相信你错误地解释了他们的答案.他们担心的是,如果你不字符串复制到一个新的数组,有人会来更改{"1","2","3"}{"a very very", "long string", "(but much longer, yes?"}之间的时间ConcatString第一次评估输入并执行串联.

请注意,第12行不处理输入数组的长度,而是处理最终输出字符串的长度.所有这些检查都处理了会话的结果,而不是输入数组.

  • 究竟.数组的长度不能改变,但数组中的*elements*可以改变,这会影响字符串的总长度. (2认同)