Thô! Tôi nghĩ rằng điều này là không thể, bởi vì reraise tương ứng với một lệnh IL đặc biệt mà lấy ngoại lệ từ phía trên cùng của ngăn xếp, nhưng cách biểu thức async được biên dịch thành chuỗi liên tục, tôi không nghĩ rằng ngữ nghĩa được giữ lại!
Đối với lý do tương tự, sau đây sẽ không biên dịch hoặc là:
try
(null:string).ToString()
with e ->
(fun() -> reraise())()
Trong những tình huống này, nơi mà tôi cần để xử lý các ngoại lệ bên ngoài của cơ thể with
thực tế, và muốn bắt chước reraise
(mà được, giữ gìn stack trace của ngoại lệ), tôi sử dụng giải pháp this, vì vậy tất cả cùng mã của bạn sẽ trông như thế:
let inline reraisePreserveStackTrace (e:Exception) =
let remoteStackTraceString = typeof<exn>.GetField("_remoteStackTraceString", BindingFlags.Instance ||| BindingFlags.NonPublic);
remoteStackTraceString.SetValue(e, e.StackTrace + Environment.NewLine);
raise e
let executeAsync context = async {
traceContext.Properties.Add("CorrelationId", context.CorrelationId)
try
do! runAsync context
return None
with
| e when isCriticalException(e) ->
logCriticalException e
reraisePreserveStackTrace e
| e ->
logException e
return Some(e)
}
cập nhật: NET 4. 5 đã giới thiệu ExceptionDispatchInfo có thể cho phép triển khai sạch hơn reraisePreserveStackTrace
ở trên.
Nguồn
2011-08-24 00:26:59
Câu trả lời này có lẽ là lỗi thời. Trong .net 4.5, bạn có thể sử dụng lớp 'ExceptionDispatchInfo', nó thực hiện điều này và cũng thu thập thông tin xô Watson như lắp ráp nguồn gốc và bù đắp IL. http://msdn.microsoft.com/en-us/library/system.runtime.exceptionservices.exceptiondispatchinfo(v=vs.110).aspx –
@DaxFohl có thể vui lòng cung cấp câu trả lời cập nhật bằng cách sử dụng 'ExceptionDispatchInfo'? –