Microsoft.Bcl.Async中是否存在ExceptionDispatchInfo的模拟?

avo*_*avo 4 .net c# task-parallel-library async-await

ExceptionDispatchInfoMicrosoft.Bcl.Async中有类似的吗?我找不到类似的东西.

这个问题是由我的另一个问题引发的.当异常的父级task可用时,我可以使用task.GetAwaiter().GetResult()@StephenCleary建议重新抛出.

当它不可用时我有什么选择?

avo*_*avo 6

这是ExceptionDispatchInfo Mono的实现.就我测试而言,它似乎与Microsoft .NET 4.0兼容.

public sealed class ExceptionDispatchInfo
{
    readonly Exception _exception;
    readonly object _source;
    readonly string _stackTrace;

    const BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic;
    static readonly FieldInfo RemoteStackTrace = typeof(Exception).GetField("_remoteStackTraceString", PrivateInstance);
    static readonly FieldInfo Source = typeof(Exception).GetField("_source", PrivateInstance);
    static readonly MethodInfo InternalPreserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace", PrivateInstance);

    private ExceptionDispatchInfo(Exception source)
    {
        _exception = source;
        _stackTrace = _exception.StackTrace + Environment.NewLine;
        _source = Source.GetValue(_exception);
    }

    public Exception SourceException { get { return _exception; } }

    public static ExceptionDispatchInfo Capture(Exception source)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        return new ExceptionDispatchInfo(source);
    }

    public void Throw()
    {
        try
        {
            throw _exception;
        }
        catch
        {
            InternalPreserveStackTrace.Invoke(_exception, new object[0]);
            RemoteStackTrace.SetValue(_exception, _stackTrace);
            Source.SetValue(_exception, _source);
            throw;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)