首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Try-Catch异步异常

Try-Catch异步异常
EN

Stack Overflow用户
提问于 2011-06-17 03:02:04
回答 1查看 7.1K关注 0票数 9

此示例“失败”:

代码语言:javascript
复制
static async void Main(string[] args)
{
    try
    {
        await TaskEx.Run(() => { throw new Exception("failure"); });
    }
    catch (Exception)
    {
        throw new Exception("success");
    }
}

也就是说,会出现文本为"failure“的异常。

然后我尝试了这个变通方法:

代码语言:javascript
复制
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刷新安装可能是软管。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-17 03:40:21

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

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

如果您将main作为async方法运行,即返回一个Task (因为返回voidasync实际上只能通过await调用)并从同步main上下文中阻塞它,您将获得适当的行为,如下面的测试所示:

代码语言:javascript
复制
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);
    }
}

也就是说,任务通过包含success异常作为其内部异常的AggregateException出错。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6377150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档