ラフ!私はこれは不可能だと思う。なぜなら、reraiseはスタックの上から例外を取る特殊なIL命令に対応するが、非同期式が連続のチェーンにコンパイルされる方法では、私はセマンティクスが成り立たないと思う!
同じ理由
、次のようにコンパイルされません、次のいずれか
私は実際
with
体の外に例外を処理する必要がある、と
reraise
をエミュレートしたいと思いますこのような状況では、
try
(null:string).ToString()
with e ->
(fun() -> reraise())()
(その、例外のスタックトレースを)維持され、私はthisソリューションを使用するので、すべて一緒にあなたのコードは次のようになります。
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)
}
更新: .NET 4。 5はExceptionDispatchInfoを導入しました。これは上記のreraisePreserveStackTrace
のよりクリーンな実装を可能にします。
内の例外をラップします。 .net 4.5では、これを行う 'ExceptionDispatchInfo'クラスを使うことができます。また、原点とILオフセットのアセンブリなどのワトソンのバケット情報も取得できます。 http://msdn.microsoft.com/en-us/library/system.runtime.exceptionservices.exceptiondispatchinfo(v=vs.110).aspx –
@DaxFohlは、「ExceptionDispatchInfo」を使用して更新された回答を提供できますか? –