Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试捕获异步异常_C#_Exception_Async Await_C# 5.0 - Fatal编程技术网

C# 尝试捕获异步异常

C# 尝试捕获异步异常,c#,exception,async-await,c#-5.0,C#,Exception,Async Await,C# 5.0,此示例“失败”: 也就是说,文本“failure”的异常出现了 然后我尝试了这个解决方法: static async void Main(string[] args) { try { await SafeRun(() => { throw new Exception("failure"); }); } catch (Exception) { throw new Exception("success"); } }

此示例“失败”:

也就是说,文本“failure”的异常出现了

然后我尝试了这个解决方法:

static async void Main(string[] args)
{
    try
    {
        await SafeRun(() => { throw new Exception("failure"); });
    }
    catch (Exception)
    {
        throw new Exception("success");
    }
}

static async Task SafeRun(Action action)
{
    var ex = default(Exception);
    await TaskEx.Run(() =>
    {
        try
        {
            action();
        }
        catch (Exception _)
        {
            ex = _;
        }
    });
    if (ex != default(Exception))
        throw ex;
}
那也没用

我想我的异步CTP刷新安装可以用软管冲洗


这段代码是否应该像我预期的那样工作(“成功”冒泡,而不是“失败”),或者这不是“应该”那样工作。如果不是,您将如何解决它?

您看到的行为可能是一个边缘案例错误,或者如果不直观,甚至可能是正确的。通常,当您同步调用异步方法时,它会将任务包装起来执行,因为没有人等待任务完成,所以异常永远不会进入主线程。如果您直接调用Main,它将成功,但是您的运行时将在另一个线程上看到“success”异常

由于main是应用程序的入口点,因此会同步调用它,很可能是因为入口点不会触发任务包装行为,因此wait无法正常运行,TaskEx.run会在自己的线程上抛出,这在运行时会显示为在另一个线程上抛出的异常

如果将main作为
async
方法运行,即返回
任务
(因为返回
void
async
只能通过
wait
调用)并从同步主上下文对其进行阻塞,那么您将获得适当的行为,如下测试所示:

static async Task Main() {
    try {
        await TaskEx.Run(() => { throw new Exception("failure"); });
    } catch(Exception) {
        throw new Exception("success");
    }
}

static async Task Main2() {
    await Main();
}

[Test]
public void CallViaAwait() {
    var t = Main2();
    try {
        t.Wait();
        Assert.Fail("didn't throw");
    } catch(AggregateException e) {
        Assert.AreEqual("success",e.InnerException.Message);
    }
    }


[Test]
public void CallDirectly() {
    var t = Main();
    try {
        t.Wait();
        Assert.Fail("didn't throw");
    } catch(AggregateException e) {
        Assert.AreEqual("success", e.InnerException.Message);
    }
}

也就是说,任务出现了一个
aggregateeexception
,其中包含success异常作为其内部异常。

它来自一个用于测试异步的控制台应用程序,因此在我的例子中,顶级方法是主要方法。@Bent我已经更新了答案,以反映您调用的方式,这可能是错误,也可能不是错误,但是是由未定义的
异步
入口点行为引起的
static async Task Main() {
    try {
        await TaskEx.Run(() => { throw new Exception("failure"); });
    } catch(Exception) {
        throw new Exception("success");
    }
}

static async Task Main2() {
    await Main();
}

[Test]
public void CallViaAwait() {
    var t = Main2();
    try {
        t.Wait();
        Assert.Fail("didn't throw");
    } catch(AggregateException e) {
        Assert.AreEqual("success",e.InnerException.Message);
    }
    }


[Test]
public void CallDirectly() {
    var t = Main();
    try {
        t.Wait();
        Assert.Fail("didn't throw");
    } catch(AggregateException e) {
        Assert.AreEqual("success", e.InnerException.Message);
    }
}