小编Chr*_*ens的帖子

C#中的异常处理是否与ECMA-335标准相矛盾?

我的理解是基于这篇很长但很棒的文章,该文章支持C#规范中列出的行为.

CLI标准(EMCA-335)显示如果没有合适的catch,运行时应立即终止..NET运行时不会这样做,而是倾向于倾向于C#规范(EMCA-334)的行为.

首先,我觉得奇怪的是语言规范似乎是定义框架行为.其次,他们似乎是矛盾的.

  • 它们是否相互矛盾,或者我是否得到了错误的文件含义?
  • 运行时是否必须以这种方式进行异常处理以符合标准?

作为一个可选的问题,哪一个是"正确的"问题,如果我要编写自己的CLI实现,我应该使用哪一个?请注意,EMCA-335(CLI)文档在两个月前更新,其中EMCA-334(C#)于2006年更新.


ECMA-335分区I第12.4.2.5节

  • 发生异常时,CLI将在阵列中搜索第一个受保护的块
    • 保护包含当前指令指针和区域的区域
    • 是一个catch处理程序块和
    • 谁的过滤器希望处理异常
  • 如果在当前方法中找不到匹配项,则搜索调用方法,依此类推.如果未找到匹配项,CLI将转储堆栈跟踪并中止该程序.

  • 如果找到匹配项,CLI会将堆栈移回到刚定位的点,但这次调用finally和fault处理程序.然后它启动相应的异常处理程序.

C#规范§15.9.5和§15.10(MSDN上的§8.9.5和§8.10)

它与CLI标准之间的主要区别在于,无论是否找到了catch块,应用程序都不会存在,但仍将展开堆栈,并处理最终的处理程序.

我建议阅读标准本身以获得更好的意义,因为下面是一个非常粗略的总结.它概述了如何使用每种可能的方案执行try语句.

  • 在引发异常的函数中:
    • 在每个try语句中查找匹配的catch子句
      • 执行catch语句(如果存在)
    • 如果存在,则执行finally块
  • 如果没有处理程序,则在调用函数中重复上述步骤
  • 如果异常处理终止当前线程中的所有函数成员调用,指示该线程没有该异常的处理程序,则该线程本身终止.这种终止的影响是实现定义的.

.net c# specifications exception-handling

23
推荐指数
2
解决办法
531
查看次数

当从finallys抛出异常时,不会评估Catch块

出现这个问题是因为以前在.NET 4.0中运行的代码在.NET 4.5中出现了未处理的异常,部分原因是try/finallys.如果您需要详细信息,请阅读Microsoft connect.我用它作为这个例子的基础,所以它可能有助于引用.

代码

对于那些选择不阅读这个问题背后细节的人来说,这里可以快速了解发生这种情况的条件:

using(var ms = new MemoryStream(encryptedData))
using(var cryptoStream = new CryptoStream(encryptedData, decryptor, CryptoStreamMode.Read))
using(var sr = new StreamReader(cryptoStream))
Run Code Online (Sandbox Code Playgroud)

这个问题是从DisposeCryptoStream方法抛出的异常(因为它们在using语句中,这些异常碰巧是从两个不同的finally块抛出的).当cryptoStream.Dispose()被召唤时StreamReader,CryptographicException被抛出.第二次cryptoStream.Dispose()调用,在其using语句中,它抛出一个ArgumentNullException

下面的代码从上面提供的链接中删除了大部分不必要的代码,并将using语句展开到try/finallys中,以清楚地表明它们正在抛出finally块.

using System;
using System.Security.Cryptography;
namespace Sandbox
{
    public class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                try
                {
                    try
                    {
                        Console.WriteLine("Propagate, my children");
                    }
                    finally
                    {
                        // F1
                        Console.WriteLine("Throwing CryptographicExecption");
                        throw new CryptographicException();
                    }
                }
                finally
                {
                    // F2 …
Run Code Online (Sandbox Code Playgroud)

.net c# specifications .net-4.5

17
推荐指数
3
解决办法
1421
查看次数

GC行为和CLR线程劫持

我正在阅读本书中关于GC的内容CLR via C#,特别是关于CLR何时想要开始收集的内容.我知道它必须在收集发生之前挂起线程,但它提到它必须在线程指令指针到达安全点时执行此操作.在它不在安全点的情况下,它会尝试快速找到一个,并且它由hijacking线程完成(在线程堆栈中插入一个特殊的函数指针).这一切都很好,花花公子,但我认为托管线程默认是安全的?

我最初认为它可能是指非托管线程,但CLR允许非托管线程继续执行,因为任何使用的对象都应该被固定.

那么,什么是safe point托管线程,GC如何确定它是什么?

编辑:

我认为我不够具体.根据这篇MSDN文章,即使Thread.Suspend被调用,该线程实际上也不会被暂停,直到safe point达到.它继续进一步说明a safe point是线程执行中可以执行垃圾收集的点.

我想我的问题不清楚.我意识到一个线程只能在安全点暂停,并且它们必须暂停用于GC,但我似乎无法找到一个明确的答案,关于什么是安全点.是什么决定了代码中的安全点?

c# clr garbage-collection

13
推荐指数
1
解决办法
1397
查看次数

无法将uint*转换为uint []

我有这个不编译的代码:

public struct MyStruct
{
    private fixed uint myUints[32];
    public uint[] MyUints
    {
        get
        {
            return this.myUints;
        }
        set
        {
            this.myUints = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我知道为什么代码不会编译,但我显然是在我太累了想不到的地方,需要一些帮助才能让我朝着正确的方向前进.我有一段时间没有处理不安全的代码,但我很确定我需要做一个Array.Copy(或Buffer.BlockCopy?)并返回一个数组的副本,但是那些不需要我需要的参数.我忘记了什么?

谢谢.

c# arrays pointers unsafe

7
推荐指数
1
解决办法
1225
查看次数

静态构造函数的性能以及为什么我们无法指定beforefieldinit

我使用以下两个结构来发现速度上的差异:

public struct NoStaticCtor
{
    private static int _myValue = 3;
    public static int GetMyValue() { return _myValue; }
}

public struct StaticCtor
{
    private static int _myValue;
    public static int GetMyValue() { return _myValue; }
    static StaticCtor()
    {
        _myValue = 3;
    }
}

class Program
{
    static void Main(string[] args)
    {
        long numTimes = 5000000000; // yup, 5 billion
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (long i = 0; i < numTimes; i++)
        {
            NoStaticCtor.GetMyValue();
        }
        sw.Stop();
        Console.WriteLine("No …
Run Code Online (Sandbox Code Playgroud)

.net c# clr performance

7
推荐指数
1
解决办法
1688
查看次数

在Jenkins中配置多个mercurial存储库

我们使用大约30个回购来处理我们公司的所有软件.我们的代码混合在C#,C++和python之间.我们最初将使用TeamCity作为我们的CI服务器,我发现使用我们的repo系统布局非常容易.但是,我的经理决定我们应该使用Jenkins.

当我开始设置Jenkins时,我发现它自然不会支持每个作业的多个存储库.有一个插件,但在维基页面上,插件的维护者承认它更像是一个概念验证,而不是一个坚实的功能,所以我对使用它犹豫不决,尽管最后,我可能被迫.

应该独立于每个仓库设置作业,还是可以运行单元测试和构建?我不认为这是一个可行的选择,因为我们的存储库相互依赖,除非我缺少配置或不同的插件.或者构建依赖于彼此可以做出这样的事情吗?

我们的最终目标是让Jenkins处理我们的开发区域的部署.事实证明,这在TeamCity中很容易实现,而且我认为在Jenkins中也应该这么容易.作业可以从其他工作中访问存储库吗?我不知道这是明确的,但在球队的城市,有项目的变量,可以让你选择你所定义的任何回购协议(即%FIRST_REPO%,%SECOND_REPO%)

总而言之,是否有一种可靠,干净的方式来处理Jenkins中的多个mercurial存储库?其他工作可以依赖另一个工作并访问另一个工作库吗?

我希望有比我更多CI经验的人可以提供帮助.也许不同的CI服务器可以更好地用于我们的设置,有没有人有使用BuildBot的经验?


我认为列出存储库的布局可能是有益的:

  • app1.application
  • app1.common
  • app1.deploy
  • app2.application
  • app2.common
  • app2.deploy
  • platform.common
  • platform.deploy

在哪里app1,app2将取决于一些资源platform.common.

build-automation mercurial continuous-integration hudson jenkins

6
推荐指数
1
解决办法
944
查看次数

为什么PCL项目中的DLL是x86程序集?

我在Visual Studio 2012中有一个C#项目是PCL,针对这些平台(我删除了名称):

在此输入图像描述

当我尝试将dll从成功构建添加到VS2013中的Silverlight 5项目时,我收到此警告并且似乎实际上没有添加:

警告1正在构建的项目的处理器体系结构"MSIL"与参考"[Name]","x86"的处理器体系结构之间存在不匹配.这种不匹配可能会导致运行时故障.请考虑通过Configuration Manager更改项目的目标处理器体系结构,以便在项目和引用之间调整处理器体系结构,或者依赖于具有与项目的目标处理器体系结构相匹配的处理器体系结构的引用.

在此输入图像描述

为什么PCL会显示为x86?

c# silverlight-5.0 portable-class-library visual-studio-2012 visual-studio-2013

6
推荐指数
1
解决办法
383
查看次数

在Null Reference上调用实例方法有时会成功

对不起文字的墙,但我想提供一个很好的背景情况.我知道你可以在IL中调用null引用的方法,但是在你理解CLR的工作方式时,仍然不会理解一些非常奇怪的事情.我在这里找到的关于这一点的其他几个问题并没有涵盖我在这里看到的行为.

这是一些IL:

.assembly MrSandbox {}
.class private MrSandbox.AClass {
    .field private int32 myField

    .method public int32 GetAnInt() cil managed {
        .maxstack  1
        .locals init ([0] int32 retval)
        ldc.i4.3
        stloc retval
        ldloc retval
        ret
    }

    .method public int32 GetAnotherInt() cil managed {
        .maxstack  1
        .locals init ([0] int32 retval)
        ldarg.0
        ldfld int32 MrSandbox.AClass::myField
        stloc retval
        ldloc retval
        ret
    }
}
.class private MrSandbox.Program {
    .method private static void Main(string[] args) cil managed {
        .entrypoint
        .maxstack  1
        .locals init ([0] class MrSandbox.AClass …
Run Code Online (Sandbox Code Playgroud)

.net clr il

1
推荐指数
1
解决办法
391
查看次数