Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.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
C# 正在使用Lazy<;T>;对性能不利?_C#_.net 4.0_Lazy Initialization - Fatal编程技术网

C# 正在使用Lazy<;T>;对性能不利?

C# 正在使用Lazy<;T>;对性能不利?,c#,.net-4.0,lazy-initialization,C#,.net 4.0,Lazy Initialization,最近,我遇到了一个singelton类的一些问题,该类懒散地初始化一个字典,第二个线程会在它实际填充之前尝试使用它。所以我通过类实现了变量初始化 这是我的密码: private static Dictionary<string, string> GroupDefaults { get { return mGroupDefaults.Value; } } private static Lazy<Dictionary<string, string>> mG

最近,我遇到了一个singelton类的一些问题,该类懒散地初始化一个字典,第二个线程会在它实际填充之前尝试使用它。所以我通过类实现了变量初始化

这是我的密码:

private static Dictionary<string, string> GroupDefaults
{
    get { return mGroupDefaults.Value; }
}
private static Lazy<Dictionary<string, string>> mGroupDefaults =
    new Lazy<Dictionary<string,string>>(delegate
    {
        Dictionary<string, string> defaults = new Dictionary<string, string>();
        foreach (KeyValuePair<string, UnitGroup> groupDef in Groups)
            defaults.Add(groupDef.Key, groupDef.Value.First().Key);
        return defaults;
    });
私有静态字典组默认值
{
获取{return mGroupDefaults.Value;}
}
私有静态惰性默认值=
新的惰性(委托)
{
字典默认值=新建字典();
foreach(组中的KeyValuePair groupDef)
添加(groupDef.Key,groupDef.Value.First().Key);
返回默认值;
});

这解决了问题,现在我正在考虑将此作为我的常规做法,在我进行延迟初始化的任何地方使用
Lazy
类,以避免任何可能的线程问题。所以基本上我想知道这是否是好的/普遍的做法?或者它会对性能或其他方面产生决定性影响?

如果不知道您有什么类型的性能约束,很难说,但根据我的经验,一次性初始化很少是一个瓶颈(因为根据定义,它只发生一次)。
Lazy
就是为了向您提供这种精确的服务而编写的,因此,我建议您使用它。

我认为您可能在使用Lazy,而不是它的预期用途。Lazy用于初始化成本较高的情况,但很可能在对象的生命周期内不使用它


如果您总是在容器的生命周期内至少调用一次
GroupDefaults
,那么更好的方法是在容器生命周期开始时在后台线程中初始化
GroupDefaults
,并希望在初始化之前完成(我知道有一个类用于此,但我需要深入到MSDN中找到它)

如果这是针对单身人士的,a可能是您想要的。比如:

class MySingleton
{
    static MySingleton()
    {
         Instance().InitDict();
    }
}

从文档中,我发现以下内容:

如果没有在惰性构造函数中传递委托, 首次访问value属性时,使用Activator.CreateInstance创建包装类型。 如果该类型没有默认构造函数,则会引发运行时异常


Activator.CreateInstance
是一种众所周知的性能不佳的方法。然而,在您的案例中,这似乎不是一个问题,而且无论如何,正如dlev所说,调用该方法一次也不会是一个问题。我没有见过经常使用的
Lazy
,但我看不出有任何理由不在您的案例中使用它。

虽然我同意这是预期的用例,但它也正确地实现了线程安全初始化,因此您不必担心自己会这样做。不过,我是从另一个线程初始化它的,在其他并排加载的东西尝试访问它之前,初始化不会完成。这是一个非常奇怪的情况,我不能按顺序加载,因为这样会增加相当多的加载时间。因此,我产生了许多线程,它们在由于GroupDefaults未初始化而受阻之前做了相当多的工作,从而加快了总体加载时间。然而,我基本上是在问使用这个类会有什么负面影响?它的缺点是什么?@AlexHopeO'Connor这就是它被添加的原因!使用该类的缺点是,字段/属性的声明变得有点混乱(如您所见),但就性能而言,它是可靠的。这就是我所需要听到的,只是我在其他人的代码中没有看到太多这样的示例。@AlexHopeO'Connor它只是在v4.0中添加到框架中,所以它没有出现那么久。再加上它是一个小类,你就很少遇到它了?如果您希望获得最佳性能,并且线程安全不是一个因素,那么我认为这应该是错误的