Rough! Penso che questo sia impossibile, perché il reraise corrisponde ad una speciale istruzione IL che afferra l'eccezione dalla cima della pila, ma il modo in cui le espressioni asincrone sono compilate in una catena di continuazioni, non credo che la semantica regga!
Per lo stesso motivo, il seguente non verrà compilato uno:
try
(null:string).ToString()
with e ->
(fun() -> reraise())()
In queste situazioni, in cui ho bisogno per gestire l'eccezione di fuori del with
corpo reale, e vorrebbe emulare reraise
(che è, conservare la traccia dello stack dell'eccezione), io uso this soluzione, quindi tutti insieme il codice sarà simile:
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)
}
Aggiornamento: .NET 4. 5 ha introdotto ExceptionDispatchInfo che potrebbe consentire un'implementazione più pulita di reraisePreserveStackTrace
precedente.
fonte
2011-08-24 00:26:59
Questa risposta è forse obsoleto. In .net 4.5 è possibile utilizzare la classe 'ExceptionDispatchInfo', che esegue questa operazione e acquisisce anche informazioni bucket Watson come assembly of origin e IL offset. http://msdn.microsoft.com/en-us/library/system.runtime.exceptionservices.exceptiondispatchinfo(v=vs.110).aspx –
@DaxFohl potrebbe fornire una risposta aggiornata usando 'ExceptionDispatchInfo'? –