【问题标题】:Parallel Extensions: Help Me Understand LazyInit<T>并行扩展:帮助我理解 LazyInit<T>
【发布时间】:2008-11-11 01:44:24
【问题描述】:

面向未来读者的更新:当 .NET 4 发布时,来自 CTP 的 LazyInit&lt;T&gt; 将被重命名为 Lazy&lt;T&gt; 并将从结构更改为类,所以很少这将适用,除非作为说明为什么如果您不小心可变结构可能会出现问题。

我一直在 Parallel Extensions June CTP 中试验 LazyInit,我希望下面的代码会打印一千次相同的 Guid,但它会打印出一千个不同的 Guid。显然,我在这里遗漏了一些关于 LazyInit 应该如何工作的明显内容,如果有人能指出它是什么,我将不胜感激。

using System;
using System.Diagnostics;
using System.Threading;

namespace TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i=0; i < 1000; i++)
            {
                Console.WriteLine(TestClass.Instance.Id);
            }

            Console.Write("Press any key to continue:");
            Console.ReadKey();
        }

        private class TestClass
        {
            private static readonly LazyInit<TestClass> _instance = new LazyInit<TestClass>(() => new TestClass(), LazyInitMode.EnsureSingleExecution);

            public static TestClass Instance
            {
                get { return _instance.Value; }
            }

            private TestClass()
            {
                Debug.WriteLine("TestClass Constructor");
                Id = Guid.NewGuid();
            }

            public Guid Id { get; private set; }
        }
    }
}

【问题讨论】:

    标签: c# parallel-extensions


    【解决方案1】:

    短版:使静态非只读,它将修复您遇到的错误。

    长版:这是 C# 中一个非常被误解的部分。当您访问一个结构时,您正在访问该结构的副本。 LazyInit.Value 的底层调用是一个变异操作。通常会执行回写,但在只读字段的情况下,无法执行回写,因此您仍然会留下未初始化的值。

    极其详细的解释:http://ericlippert.com/2008/05/14/mutating-readonly-structs/

    【讨论】:

    • 谢谢,我回来用相同的 URL 回答我自己的问题,但你打败了我!
    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2011-01-26
    • 1970-01-01
    相关资源
    最近更新 更多