无法从Task.Run捕获异常

时间:2016-10-25 03:34:06

标签: c# .net async-await task

我正在关注此MSDN guide来处理任务中的异常。

这就是我写的:

var myTask = Task.Run(() =>
    {
        throw new Exception("test");
    });
try
{
    myTask.Wait();
}
catch (Exception e)
{
    return false;
}

我在catch块中设置了一个断点,但在调试运行时,代码没有到达断点,它给了我:

  

用户代码

未处理异常

我不知道发生了什么,因为我非常密切关注MSDN指南中的示例。实际上,我将示例复制到了我的项目中,它仍然存在同样的问题。

我可以在Task之外处理异常吗?如果任务抛出任何异常,我需要根据事实返回一个布尔值。

修改

为了让你们中的一些人更清楚,这是一套更完整的代码:

public bool ConnectToService()
{
    try
    {
        // Codes for ServiceHost etc etc, which I'm skipping
        // These codes are already commented out for this test, so they do nothing

        var myTask = Task.Run(() =>
            {
                // Supposed to connect to a WCF service, but just throwing a test exception now to simulate what happens when the service is not running
                throw new Exception("test");
            });
        try
        {
            myTask.Wait();
        }
        catch (Exception e)
        {
            return false;
        }

        return true;
    }

    catch (Exception)
    {
        return false;
    }
}

呼叫者:

public void DoSomething()
{
    try
    {
        // Other irrelevant stuff
        if (ConnectToService())
        {
            DoAnotherThing();
        }
    }
    catch (Exception)
    {
    }

}

我还想指出我有一个解决方案,但令人费解的是为什么MSDN的一个例子对我不起作用。我认为我自己的解决方案并不优雅,所以我仍然在寻找更优雅的解决方案。

Exception taskException = null;
var myTask = Task.Run(() =>
    {
        try
        {
            throw new Exception("test");
        }
        catch (Exception e)
        {
            taskException = e;
        }
    });
try
{
    myTask.Wait();
    if (taskException != null) throw taskException;
}
catch (Exception e)
{
    return false;
}

4 个答案:

答案 0 :(得分:2)

当一个任务运行时,任何等待任务结果或完成任务的事件都会保留并重新抛出它抛出的任何异常

task.Wait()  Rethrows any exceptions

task.Result  Rethrows any exceptions

同样,您的代码也能正常运行

只需在捕获异常时按f5,您就会看到这将获得您的观点

答案 1 :(得分:1)

根据to MSDN Task.Run:

  

将指定的工作排队以在线程池上运行,并返回表示该工作的Task对象。

所以你把异常抛到了不同的线程上,而不是试图抓住它。你应该在同一个线程上处理异常。

或者,您可以在AppDomain.UnhandledException

中处理未处理的例外情况

答案 2 :(得分:0)

Jai,如上所述,此代码将始终有效。我想你必须在visual studio中启用一些设置。该设置已关闭,因此,您将获得"异常不由用户代码处理"。

尝试检查工具,选项,调试,常规,仅启用我的代码。

此外,如果您不想尝试/捕捉东西,可以使用下面的内容:

myTask.ContinueWith(<you can access Exception property here to see if there was an exception>)

答案 3 :(得分:0)

@Jai,请尝试将Task.Run移动到try / catch块的内部。我认为Task.Run执行imediatelly因此你可能会因此而异常。