投掷VS反对:同样的结果? [英] Throw VS rethrow : same result?

查看:173
本文介绍了投掷VS反对:同样的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参考网上的大量文档,特别是在SO上,例如:在C#中重新抛出异常的正确方法是什么?
应该在throw e之间有所区别和扔。



但是,从: http://bartdesmet.net/blogs/bart/archive/2006/03/12/3815.aspx



这段代码:

  using System; 

class Ex
{
public static void Main()
{
//
//首先测试重新抛出捕获的异常变量。
//
Console.WriteLine(First test);
try
{
ThrowWithVariable();
}
catch(Exception ex)
{
Console.WriteLine(ex.StackTrace);
}

//
//第二次测试执行盲目推翻。
//
Console.WriteLine(Second test);
try
{
ThrowWithoutVariable();
}
catch(Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}

private static void BadGuy()
{
//
//有些讨厌的行为。
//
throw new Exception();
}

private static void ThrowWithVariable()
{
try
{
BadGuy();
}
catch(Exception ex)
{
throw ex;
}
}

private static void ThrowWithoutVariable()
{
try
{
BadGuy();
}
catch
{
throw;
}
}
}

给出以下结果: / p>

  $ /cygdrive/c/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe Test.cs 
Microsoft(R)Visual C#2010编译器版本4.0.30319.1
版权所有(C)Microsoft Corporation。版权所有。

$ ./Test.exe
首先测试
在Ex.ThrowWithVariable()
在Ex.Main()
第二个测试
在Ex.ThrowWithoutVariable()
在Ex.Main()

这是完全矛盾的与博客文章。



使用以下代码获得同样的结果: http://crazorsharp.blogspot.com/2009/08/rethrowing-exception-without-resetting.html

$



更新:相同的结果.Net 3.5 / csc.exe 3.5.30729.4926



SUMUP :所有的答案都很棒,再次感谢。

所以原因是由于64位JITter有效内联。



我只能选择一个答案,而在这里是为什么我选择了LukeH 答案:




  • 他猜到了内联问题,以及与64位架构有关的事实,





但是这个问题现在提出另一个问题:是否符合所有.Net规范:CLR和C#编程语言?



更新:此优化似乎符合以下条件:投掷VS重掷:相同结果?(感谢 0xA3



提前感谢您的帮助。

解决方案

我无法复制问题 - 使用.NET 3.5(32位)给出了与Bart的文章相同的结果。



我的猜测是.NET 4编译器/抖动 - 或者也许是64位编译器/ j如果这种情况发生在3.5以下,那么 - 将 BadGuy 方法嵌入到调用方法中。尝试添加以下 MethodImpl 属性到 BadGuy ,看看是否有所作为:

  [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] 
private static void BadGuy()
{
//
// Some讨厌的行为。
//
throw new Exception();
}


refering to a lot of documentation on the net, particularly on SO, eg : What is the proper way to re-throw an exception in C#? there should be a difference between "throw e;" and "throw;".

But, from : http://bartdesmet.net/blogs/bart/archive/2006/03/12/3815.aspx,

this code :

using System;

class Ex
{
   public static void Main()
  {
  //
  // First test rethrowing the caught exception variable.
  //
  Console.WriteLine("First test");
  try
  {
     ThrowWithVariable();
  }
  catch (Exception ex)
  {
     Console.WriteLine(ex.StackTrace);
  }

  //
  // Second test performing a blind rethrow.
  //
  Console.WriteLine("Second test");
  try
  {
     ThrowWithoutVariable();
  }
  catch (Exception ex)
  {
     Console.WriteLine(ex.StackTrace);
  }
}

 private static void BadGuy()
 {
   //
   // Some nasty behavior.
  //
   throw new Exception();
 }

   private static void ThrowWithVariable()
 {
   try
   {
         BadGuy();
   }
  catch (Exception ex)
  {
     throw ex;
  }
}

   private static void ThrowWithoutVariable()
{
  try
  {
     BadGuy();
  }
  catch
  {
     throw;
  }
   }
}

gives the following result :

$ /cygdrive/c/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe Test.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

$ ./Test.exe
First test
   at Ex.ThrowWithVariable()
   at Ex.Main()
Second test
   at Ex.ThrowWithoutVariable()
   at Ex.Main()

which is in complete contradiction with the blog post.

The same kind of result is obtained with the code from : http://crazorsharp.blogspot.com/2009/08/rethrowing-exception-without-resetting.html

Original question : what am I doing wrong ?

UPDATE : same result with .Net 3.5 / csc.exe 3.5.30729.4926

SUMUP : all your answers were great, thanks again.

So the reason is effectively inlining due to the 64-bit JITter.

I had to choose only one answer, and here is why I have choosen LukeH answer :

  • he guessed the inlining problem and the fact it may be related to my 64-bit architecture,

  • he provided the NoInlining flag which is the simplest way to avoid this behavior.

However this issue now rises another question : is this behavior compliant with all the .Net specifications : the CLR ones and the C# programming language ones ?

UPDATE : this optimization seems compliant according to : Throw VS rethrow : same result? (thanks 0xA3)

Thanks in advance for your help.

解决方案

I can't replicate the problem -- using .NET 3.5 (32-bit) gives me the same results described in Bart's article.

My guess is that the .NET 4 compiler/jitter -- or maybe it's the 64-bit compiler/jitter if this is happening under 3.5 too -- is inlining the BadGuy method into the calling methods. Try adding the following MethodImpl attribute to BadGuy and see if that makes any difference:

[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static void BadGuy()
{
    //
    // Some nasty behavior.
    //
    throw new Exception();
}

这篇关于投掷VS反对:同样的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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