0%

Throw 和 Throw ex

在C#中,throwthrow ex都用于抛出异常,但它们在异常堆栈跟踪处理上有重要区别。

  • throw ex resets the stack trace (so your errors would appear to originate from HandleException) 重置堆栈跟踪

  • throw does not - the original offender would be preserved. 保留堆栈跟踪

Throw

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (Exception)
{
Console.WriteLine("An error occurred.");

throw;
}
}

static void SomeMethod()
{
throw new NotImplementedException();
}
}

运行堆栈:

1
2
3
4
An error occurred.
Unhandled exception. System.NotImplementedException: The method or operation is not implemented.
at SomeMethod() in Test.cs:line 18
at Main(String[] args) in Test.cs:line 6

保留了完整的堆栈跟踪

Throw preserves the stack trace. So lets say Source1 throws Error1 , its caught by Source2 and Source2 says throw then Source1 Error + Source2 Error will be available in the stack trace.


Throw ex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (Exception ex)
{
Console.WriteLine("An error occurred.");

throw ex;
}
}

static void SomeMethod()
{
throw new NotImplementedException();
}
}

通常你会看到一个 build warning:
Rethrow to preserve stack details: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2200

运行堆栈:

1
2
3
An error occurred.
Unhandled exception. System.NotImplementedException: The method or operation is not implemented.
at Main(String[] args) in Test.cs:line 12

重置堆栈跟踪,丢失原始抛出位置信息

Throw ex does not preserve the stack trace. So all errors of Source1 will be wiped out and only Source2 error will sent to the client.

throw_or_throw_ex