Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Is.NET';StringBuilder线程安全_.net_Thread Safety_Stringbuilder - Fatal编程技术网

Is.NET';StringBuilder线程安全

Is.NET';StringBuilder线程安全,.net,thread-safety,stringbuilder,.net,Thread Safety,Stringbuilder,StringBuilder的MSDN文档的常规“线程安全”部分说明: …不保证任何实例成员是线程安全的 但这条语句感觉像是对框架中几乎每个类都进行了复制和粘贴: 然而,Gavin Pugh的这些博客文章提到了StringBuilder的线程安全行为: 此外,Reflector披露了StringBuilder的来源以及附带的注释 在SSCLI源代码中,还建议了许多实现注意事项,以确保线程安全: 是否有人更了解在多个并发线程之间共享一个StringBuilder实例是否安全?本文档的全部目的

StringBuilder
的MSDN文档的常规“线程安全”部分说明:

…不保证任何实例成员是线程安全的

但这条语句感觉像是对框架中几乎每个类都进行了复制和粘贴:

然而,Gavin Pugh的这些博客文章提到了
StringBuilder的线程安全行为:

此外,Reflector披露了StringBuilder的来源以及附带的注释 在SSCLI源代码中,还建议了许多实现注意事项,以确保线程安全:


是否有人更了解在多个并发线程之间共享一个
StringBuilder
实例是否安全?

本文档的全部目的是为您提供保证。在这种情况下,对于实例成员,没有任何东西可以保证线程安全,您应该将其视为线程安全,因此依赖于外部同步方法

有些东西可能是线程安全的,这是一个实现细节,它可以而且可能确实从一个版本的框架更改到下一个版本,或者从一个实现更改到下一个版本(事实上,在框架版本中有很多这样的细节在更改;Eric Lippert有一些文章详细介绍了其中的一些细节)。不要依赖它


(换句话说:不要向实现编写代码,而是根据接口和契约编写代码,在本例中,接口和契约是类及其文档的元数据。)

绝对不是;下面是一个通过reflector从4.0升级的简单示例:

[SecuritySafeCritical]
public StringBuilder Append(char value)
{
    if (this.m_ChunkLength < this.m_ChunkChars.Length)
    {
        this.m_ChunkChars[this.m_ChunkLength++] = value;
    }
    else
    {
        this.Append(value, 1);
    }
    return this;
}
从:

此类型的任何公共静态(在Visual Basic中共享)成员都是 线程安全。不保证任何实例成员都是线程 安全的


String.Builder
直到3.5版本仍然包含线程检查代码。有关更多详细信息,请参阅。
var gate = new ManualResetEvent(false);
var allDone = new AutoResetEvent(false);
int counter = 0;
var sb = new StringBuilder();
ThreadStart work = delegate
{
    // open gate when all 5 threads are running
    if (Interlocked.Increment(ref counter) == 5) gate.Set();
    else gate.WaitOne();

    for (int i = 0; i < 1000; i++) sb.Append("a");

    if (Interlocked.Decrement(ref counter) == 0) allDone.Set();
};
for(int i = 0 ; i < 5 ; i++)
{
    new Thread(work).Start();
}
allDone.WaitOne();
Console.WriteLine(sb.Length);