简体   繁体   English

自从使用.Net 4.0以来,Visual Studio的发布模式中出现InvalidOperationException

[英]InvalidOperationException in release-mode of visual studio since using .Net 4.0

I have some trouble to port an existing .NET 3.5 Application to .NET 4.0. 将现有的.NET 3.5应用程序移植到.NET 4.0有些麻烦。 The Code isn't written by myself so I didn´t know in detail why the things are as they are. 该守则不是我自己编写的,所以我不知道为什么事情就像它们一样。

This is the Situation: Code works fine if the application is started from Visual Studio (Release or Debug-Mode doesn't matter) and also if the application is started form Debug-folder The Problem is the Release-deploy, because is doesn't work well since 4.0 (and also in 4.5) :-/ 这是情况:如果从Visual Studio启动应用程序(版本或调试模式无关紧要),并且如果应用程序从Debug-folder启动,则代码工作正常问题是版本部署,因为它不是'自4.0(以及4.5)以来运作良好: - /

This is the initial call: 这是最初的电话:

someObject.Text = Elements.GetElement(Int16.Parse(cb1.Text));

And Here is the code: 这是代码:

public class Elements : EnumBase<int, Elements>
{
    public static readonly Elements Element1 = Create("Number 0", 0);
    public static readonly Elements Element2 = Create("Number 1", 1);

    private static Elements Create(string text, int value) 
    {
        return new Elements() { text = text, value = value };
    }

    public static String GetElement(int id)
    {

        // The Following Code safes the day and let the release deploy work fine.
        // It doesn´t matter if the condition becomes true or not to runtime.
        /* 
        if (id == 999999999)
        {
            Elements el = Element1;
        }
        */

        // Release deploy works also fine if you do the following line in a loop instead of linq.
        return BaseItemList.Single(v => v.Value == id).Text; 
    }
}

[Serializable()]
public class EnumBase<T, E> :  IEqualityComparer<E> 
        where E : EnumBase<T, E>
{
    private static readonly List<E> list = new List<E>();
    protected string text;
    protected T value;

    protected static IList<E> BaseItemList
    {
        get
        {
            return list.Distinct(new EnumBase<T, E>(false)).ToList();
        }
    }

    protected EnumBase()
    {
        list.Add(this as E);
    }

    /// <summary>
    /// Constructor for distinct to avoid empty elements in the list
    /// </summary>   
    private EnumBase(bool egal) {}

    public string Text
    {
        get { return text; }
    }

    public T Value
    {
        get { return value; }
    }


    #region IEqualityComparer<E> Member

    // ...

    #endregion
}

The key is return BaseItemList.Single(v => v.Value == id).Text; 关键是return BaseItemList.Single(v => v.Value == id).Text; . It throws a InvalidOperationException , because in Release public static readonly Elements Element1 = Create("Number 0", 0); 它抛出一个InvalidOperationException ,因为在Release public static readonly Elements Element1 = Create("Number 0", 0); and public static readonly Elements Element2 = Create("Number 1", 1); public static readonly Elements Element2 = Create("Number 1", 1); aren't ready. 尚未准备好 In the moment of the Exception is BaseItemList empty (BaseItemList.Count = 0). 在异常时刻,BaseItemList为空(BaseItemList.Count = 0)。 I am not sure why this happened in release form bin-folder and not in release out of visual studio. 我不确定为什么这发生在发布形式的bin-folder中,而不是发布在visual studio中。 For tests I deactivated "Optimize code" in project-properties but it doesn't help. 对于测试,我在项目属性中停用了“优化代码”,但它没有帮助。

Surely the construct isn't the best, but I want to know what is different in .Net 4.0 that bring the code to flatter. 当然,构造不是最好的,但我想知道.Net 4.0中的不同之处使代码变得更加平坦。

Thanks for help 感谢帮助

I believe the problem is that you're relying on the static initializer for Elements having run, despite the fact that you haven't referred to any fields within it. 我相信问题是你依赖于运行的Elements的静态初始化器,尽管你没有引用其中的任何字段。 The type initializer in a type which doesn't have a static constructor is only guaranteed to run before the first static field access. 没有静态构造函数的类型中的类型初始化程序仅保证在第一次静态字段访问之前运行。 Section 10.5.5.1 of the C# 5 specification: C#5规范的第10.5.5.1节:

If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. 如果类中存在静态构造函数(第10.12节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。 Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class. 否则,静态字段初始化器在第一次使用该类的静态字段之前的实现相关时间执行。

And section 10.12 has: 第10.12节有:

The static constructor for a closed class type executes at most once in a given application domain. 封闭类类型的静态构造函数在给定的应用程序域中最多执行一次。 The execution of a static constructor is triggered by the first of the following events to occur within an application domain: 静态构造函数的执行由应用程序域中发生的以下第一个事件触发:

  • An instance of the class type is created. 创建类类型的实例。
  • Any of the static members of the class type are referenced. 引用类类型的任何静态成员。

The implementation of type initialization changed in .NET 4 , but it was only an implementation detail - your code was broken before, you just didn't know it. 类型初始化的实现在.NET 4中已更改 ,但它只是一个实现细节 - 您的代码之前已被破坏,您只是不知道它。

If you change your code to have: 如果您将代码更改为:

static Elements() {}

in the Elements class, then I believe it will work - because static constructors force type initialization to occur before immediately the first member access, rather than just "at some point before the first field access". Elements类的话,我相信它会工作-因为在此之前,立即在第一构件访问发生静态构造函数力类型的初始化,而不是仅仅“在第一接入之前的一些点”。

Personally I'm dubious about the general pattern, but that's a slightly different matter. 就个人而言,我对一般模式持怀疑态度,但这是一个略有不同的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#Microsoft Visual Studio发行模式 - C# Microsoft Visual Studio Release Mode 从Visual Studio 2010 Ultimate中运行NUnit 2.5.5测试,并使用.NET 4.0代码? - Run NUnit 2.5.5 tests from within Visual Studio 2010 Ultimate and using .NET 4.0 code? Visual Studio 2010-发布模式下的应用程序即服务 - Visual studio 2010- Application as a service in release mode Visual Studio 2010-无法在发布模式下生成解决方案 - Visual Studio 2010 - Can't generate a solution in release mode Visual Studio发布使用调试模式而不是发布 - Visual Studio publish uses debug mode instead of release Visual Studio 2015 Update 2 在发布模式下编译时挂起 - Visual Studio 2015 Update 2 hangs when compiling in Release mode Visual Studio:在“调试”模式下生成,但文件仍在“发布”文件夹中生成 - Visual Studio: Building in Debug mode but the files still built in Release folder Visual Studio Xamarin 在发布模式下缺少程序集引用 - Missing assembly reference in Release mode in Visual Studio Xamarin Visual Studio Profiler与发布模式-有什么区别? - Visual Studio Profiler vs. Release Mode - what is the difference? 创建PCL NET 4.0在Visual Studio 2015中给出了一个错误 - Creating a PCL NET 4.0 gives me an error in Visual Studio 2015
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM