任务之外的异常处理 [英] Exception handling outside of Task

查看:32
本文介绍了任务之外的异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

刚刚注意到奇怪的事情:要从新任务的调用者中捕获异常,必须将 lambda 标记为异步!?即使委托根本没有等待操作符,它真的有必要吗?

Just noticed strange thing: to catch exception in caller from new Task, lambda MUST be marked as async!? Is it really necessary even if delegate has no await operators at all?

    try
    {
        //Task.Run(() =>      // exception is not caught!
        Task.Run(async () =>  // unnecessary async!?!   
        {
            throw new Exception("Exception in Task");
        }).Wait();
    }
    catch (Exception ex)
    {
        res = ex.Message;
    }

为什么需要异步操作符?我能找到的所有文档都表明委托不能返回 Void,并且必须等待 Task 以将异常传播给调用者.

Why there is neccesary for async operator? All documentation i can find tells that delegate must not return Void and Task must be awaited for exception to propogate up to caller.

添加完整代码:

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        p.Run();
    }

public void Run()
{
    string result;

    try
    {
        result = OnSomeEvent((s, ea) => RunSomeTask());
    }
    catch (Exception ex) // Try to catch unhandled exceptions here!
    {
        result = ex.Message;
    }

    Console.WriteLine(result);
    Console.ReadKey();
}

// Some other Framework bult-in event (can not change signature)
public string OnSomeEvent(EventHandler e)
{
    e.Invoke(null, new EventArgs());
    return "OK";
}

private async Task RunSomeTask()
{
    await Task.Run(async () => // do not need async here!!!
    //await Task.Run(() =>     // caller do not catches exceptions (but must)
    {
        throw new Exception("Exception in Task1");
    });
}
}

所以问题是如何抓住前任.没有 asyn 关键字???

So the qestion is how to catche ex. without asyn keyword???

推荐答案

返回 Task 的方法 - 例如 Task.Runasync方法 - 将在返回的 Task 上放置任何异常.以某种方式观察该异常取决于您.通常这是通过 await 完成的,就像这样:

Methods that return Task - such as Task.Run or async methods - will place any exceptions on that returned Task. It's up to you to observe that exception somehow. Normally this is done with await, like this:

await Task.Run(() => { throw ... });

就您而言,问题出在这一行:

In your case, the problem is in this line:

result = OnSomeEvent((s, ea) => RunSomeTask());

在这段代码中,RunSomeTask 正在返回一个 Task,并且从不等待 Task.为了观察异常,你应该await那个任务.

In this code, RunSomeTask is returning a Task, and that Task is never awaited. In order to observe the exception, you should await that task.

这篇关于任务之外的异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆