String.Concat和线程安全吗? [英] String.Concat and thread safety?

查看:143
本文介绍了String.Concat和线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问了这个问题之后,我还有一个问题.

我都得到了很好的答案,但是我仍然很难找到如何实际发生这种情况:(如何发生故障情况):

我将从一个示例开始:

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);
}

带注释的行可以在不同的线程中执行,但是每个线程都有其自己的 g变量!
(并且请记住,我不能将项目添加到错误中.因为数组长度是在创建时创建的)

无论我将如何使用函数 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   }

我的说法是:一旦我在线程X中的#1上,该线程将永远具有长度为3的数组.

如果另一个线程想要破坏/更改数组的长度(我无法理解如何,导致数组具有固定的长度,那么他只能做的是null)-它将具有不同的指针地址副本.

我一定在这里想念些东西.

  • 我想念什么?

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

解决方案

其他线程可能执行的代码将导致错误?

string[] data = { "1", "2", "3" };
ThreadPool.QueueUserWorkItem( () => { data[0] = "one"; } );
string total = String.Concat(data);

在没有中间数组的情况下会出现竞争情况,线程可能会在将其长度添加到totalLength之后在之前更改data[0] ,但是之前(可能不安全) )调用ConcatArray().然后,低级方法会将5个字符复制到大小为3的缓冲区中.

After asking this question , I still have a question.

I got both excellent answers but I'm still having a trouble finding how could this actually be occur: ( how could a fault situation can occur) :

I will start with an example :

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);
}

the notated line can be execute in a different thread but each thread has its own g variable !
(and please remember that I can't add items to an arrray. cause array length is created at creation)

No matter what will I do with the function Do - (no matter in what thread) , the Console.Writeline result will always be 3 ( unless using ref).

so lets see the real code :

    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   }

My saying is : once I'm on #1 , in thread X , this thread will forever will have array with length 3.

If another thread wants to destroy/change the array length ( which I cant understand how , cause the array has fixed length , all he can do is making it null) - it will have a different copy of pointer address.

I must be missing something here.

  • What am I missing ?

  • what is the code which other thread could execute which will cause an error ?(assuming we don't copy the array).

解决方案

what is the code which other thread could execute which will cause an error ?

string[] data = { "1", "2", "3" };
ThreadPool.QueueUserWorkItem( () => { data[0] = "one"; } );
string total = String.Concat(data);

Without the intermediate array there would be a race condition, the Thread could change data[0] after its length was added to totalLength but before the (presumably unsafe) call to ConcatArray(). The low-level method would then copy 5 chars to a buffer of size 3.

这篇关于String.Concat和线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆