c# - 在同步调用的异步代码中捕获异常

标签 c# .net exception asynchronous asp.net-membership

我有用于身份验证的 thrift 服务。 catch (AccountNotFoundException) 不会捕获异常,除非我在 Task.Run 中调用它。奇怪的是测试用例没问题。为什么?是因为 task.start() 与 catch 处于不同级别吗?

    public override string GetUserNameByEmail(string email)
    {
         var task = client.GetUserByEmail(email, false);
         return task.Result;
         // I changed to
         // return Task.Run(() => client.GetUserByEmail(email, false)).Result.UserName;
         // and I was able to catch the exception
    }

    public async Task<AccountDetails> GetAccountDetailsByEmail(string email)
    {
        try
        {
            return await Call(() => client.getAccountDetailsByEmail(email));
        }
        catch (AccountNotFoundException)
        {
            return null;
        }
    }

    private async Task<T> Call<T>(Func<T> call)
    {
        try
        {
            transport.Open();
            var thriftTask = new Task<T>(call);
            thriftTask.Start();
            return await thriftTask;
        }
        catch (DatabaseException e)
        {
            Logger.Error(e);
            throw;
        }
        finally
        {
            transport.Close();
        }
    }

测试用例工作正常

    [TestMethod]
    public async Task Nonexisting_User_I_Expect_To_Be_Null()
    {
        var user = Provider.GetUser("idontexist@bar.com", false);
        Assert.IsNull(user);
    }

编辑:

为什么我的代码运行正常,我有以下理论:代码运行正常是因为我很幸运。请求和异步由同一个线程处理,因此它们共享相同的上下文,因此不会阻塞。

最佳答案

首先,您不应该同步调用异步方法。正如我在我的博客上描述的那样,approach you're using is prone to deadlocks .

您看到意外异常类型的原因是 Result 会将所有任务异常包装在 AggregateException 中。为避免这种情况,您可以调用 GetAwaiter().GetResult()

这与 Start 没有任何关系,但既然你提到了它,Start 成员实际上并没有用例。从来没有充分的理由使用它。相反,使用 Task.Run:

var thriftTask = Task.Run(call);

关于c# - 在同步调用的异步代码中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28708238/

相关文章:

python - 引发 Exception 类和 Exception 实例之间有区别吗?

android - 单击 ListView 项时,未执行任何操作且 LogCat 显示 ViewPostImeInputStage ACTION_DOWN

C# Discord 机器人错误 : Newtonsoft. Json.JsonReaderException

c# - 无法加载文件或程序集 'Office, Version=15.0.0.0'

.net - 我什么时候应该使用 UdpClient.BeginReceive?什么时候应该在后台线程上使用 UdpClient.Receive?

c# - 在 .NET 中将单个值转换为两个 UInt16 值

c# - 自动过滤电子表格齿轮

C# 事件 : How to process event in a parallel manner

c# - 接受两个接口(interface)之一的方法

c# - 使用 ViewBag 时出现 RuntimeBinderException