并行扩展:帮助我理解LazyInit< T> [英] Parallel Extensions: Help Me Understand LazyInit<T>

查看:137
本文介绍了并行扩展:帮助我理解LazyInit< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Update for future readers: When .NET 4 comes out, LazyInit<T> from the CTP will have been renamed to Lazy<T> and will be changed from a struct to a class, so very little of this will apply, except as an illustration of why mutable structs can be problematic if you're not careful.

我在Parallel Extensions June CTP中试验了LazyInit,我希望下面的代码一千次打印出相同的Guid,打印出一千个不同的Guids。显然,我缺少一些明显的在这里如何LazyInit应该工作,如果有人愿意指出它是什么。

I've been experimenting with LazyInit in the Parallel Extensions June CTP, and I would expect the following code to print out the same Guid a thousand times, but instead it prints out a thousand different Guids. Clearly I'm missing something obvious here about how LazyInit is supposed to work, and I'd appreciate if someone would kindly point out what it is.

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


推荐答案

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

Short Version: Make the static non-readonly and it will fix the bug you are experiencing.

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

Long Version: This is a very misunderstood portion of C#. When you access a struct you are accessing a copy of the struct. The underlying call of LazyInit.Value is a mutating operation. Normally a copyback is performed but in the case of a read-only field there is no way to perform the copy back and hence you are still left with an uninitialized value.

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

这篇关于并行扩展:帮助我理解LazyInit&LT; T&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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