并行扩展:帮助我理解LazyInit <t> </t>

时间:2008-11-11 01:44:25

标签: c# parallel-extensions

未来读者的更新:当.NET 4发布时,来自CTP的LazyInit<T>将被重命名为Lazy<T>,并将从结构更改为类因此,除非作为一个例子说明为什么如果你不小心可变结构可能会有问题,所以这一点很少适用。

我在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; }
        }
    }
}

1 个答案:

答案 0 :(得分:12)

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

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

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