【问题标题】:catch exception from awaited async function从等待的异步函数中捕获异常
【发布时间】:2015-12-08 00:57:57
【问题描述】:

我得到了以下信息:

public async Task<bool> IsAuthenticatedAsync()
    {
        using (HttpClient client = new HttpClient())
        {
            using (MultipartFormDataContent content = new MultipartFormDataContent())
            {
                content.Add(new StringContent(this.Username, Encoding.UTF8), "username");
                content.Add(new StringContent(this.Password, Encoding.UTF8), "password");
                try
                {
                    HttpResponseMessage message = await client.PostAsync(authenticatedUrl, content);
                    if (message.StatusCode == HttpStatusCode.Accepted)
                        return true;
                    return false;
                }
                catch(HttpRequestException)
                {
                    System.Windows.Forms.MessageBox.Show("Some text.");
                }
            }
        }
        return false;
    }

其中authenticatedUrl 是一些静态Uri

现在假设网络服务器不可用(或地址错误)await client.PostAsync(authenticatedUrl, content) 抛出 HttpRequestException,因此是 try-catch

问题是异常没有被捕获。我尝试关闭Just My Code,但这只是按照here 的建议添加了其他异常(即SocketException),并且仍然没有让catch 处理异常。

为什么没有捕获到异常?

编辑

主窗体(GUI):

public GUI(...)
{
    ...
    CheckLoginState(username, password);
    ...
}

private async void CheckLoginState(string username, string password)
{
    User user = new User(username, password);
    if (user.Username != null && user.Password != null && await user.IsAuthenticatedAsync())
        abmeldenToolStripMenuItem.Enabled = true;
}

【问题讨论】:

  • 你有没有试过抓AggregateException
  • 您确定正在抛出HttpRequestException 吗?尝试启用第一次机会例外
  • 我在调试器中获得了System.Net.Http.HttpRequestException(第一次机会)。
  • @IvanStoev 我做了,仍然抛出了 System.Net.Http.HttpRequestException,而 try-catch 没有捕获到。
  • "显示调试器异常窗口,如果你没有捕获异常" -- 除非在 Debug/Exceptions... 设置中你已经告诉调试器总是中断异常。鉴于您描述的代码和操作,这是您关注的最有可能的解释。如果您检查了设置并确定它们与您期望的一样,则需要提供a good, minimal, complete code example 以可靠地重现问题。您显示的代码中没有任何内容可以暗示除预期结果之外的任何内容。

标签: c# async-await httpclient


【解决方案1】:

我很确定异常没有被捕获,因为它包含在从调用“CheckLoginState”方法返回的任务中,并且由于您没有等待该任务,因此您的异常将永远不会被抛出。从外观上看,您是从构造函数调用它,所以我假设您不能将“公共 GUI”变成“公共异步无效 GUI”。

为了测试,您可以尝试阻塞等待:

public GUI(...)
{
    ...
    var task = CheckLoginState(username, password).Wait();
    if(task.IsFaulted && task.Exception != null)
    {
        throw task.Exception
    }
    ...
}

另一种方法是让 async/await 模式自然传播并将其绑定到一个事件(不知道您使用的是 wpf 还是 winforms,所以我假设 wpf)。

public GUI(...)
{
    this.Loaded += async (obj, eventArgs) => await CheckLoginState(username, password);
    ...
}

当然,它不一定是“加载”事件。关键是,事件可以是异步的,而构造函数不能(据我所知)。

【讨论】:

    猜你喜欢
    • 2014-12-01
    • 2017-03-23
    • 2016-04-16
    • 2022-07-06
    • 2022-07-06
    • 2015-09-27
    • 2020-08-24
    • 2015-07-17
    • 2017-10-24
    相关资源
    最近更新 更多