异步调用中的异常会扰乱执行

Posted

技术标签:

【中文标题】异步调用中的异常会扰乱执行【英文标题】:Exception in asynchronous call messes up execution 【发布时间】:2021-02-24 18:14:29 【问题描述】:

我正在拨打两个httpClient.GetAsync() 电话。

根据要求,两个调用之一将始终抛出 “No host known” 异常,一个将返回正确的 HttpResponseMessage 对象。

我的问题是在两个异步 httpClient 调用完成后确定布尔值。

public async Task<bool> BothHttpCallsTask(string hostName)

    bool response1 = false;
    bool response2 = false;
    try
    
        //httpClient and the GetAsync() are inside this method
        response1 = await CheckRedirectionBool(url1); 
        response2 = await CheckRedirectionBool(url2);
    
    catch(Exception e)
    
        //when exception is caught here, the method evaluates as false
        //as response2  is still not executed
    
    return response1 || response2 ;

如何使执行仅在两个异步调用成功完成时才进行评估(请记住,强制异常使 return 语句在响应 2 可以从其执行中获取值之前进行评估) 如果两个 http 调用之一成功,我需要返回 true。

【问题讨论】:

你能简单地将每一个都包装在它自己的异常处理程序中吗?这样你就知道过去是哪一个等等。 我同意@JonH 哇,原来如此。感谢您的评论,我将其添加为答案 我在 CheckRedirectionBool 中确实有异常处理,但异常没有被捕获,仅在 BothHttpCallsTask 为异步 http 调用放置 try catch 块的最佳做法是什么?如果您有任何资源,我将不胜感激被重定向到那里 【参考方案1】:

我的问题是只有在两个异步 httpClient 调用完成后才确定布尔值。

如果你想像返回false一样对待异常,那么我建议编写一个小助手方法:

async Task<bool> TreatExceptionsAsFalse(Func<Task<bool>> action)

  try  return await action(); 
  catch  return false; 

那么使用Task.WhenAll就变得更简单了:

public async Task<bool> BothHttpCallsTask(string hostName)

  var results = await Task.WhenAll(
      TreatExceptionsAsFalse(() => CheckRedirectionBool(url1)),
      TreatExceptionsAsFalse(() => CheckRedirectionBool(url2))
  );
  return results[0] || results[1];

【讨论】:

谢谢!我实际上使用了两个 try catch 块,但它看起来真的很倒退。我今天一时兴起检查了这个问题,看看它是否有更新,这种方法效果很好。它确实概述了我对异步世界缺乏了解。【参考方案2】:

你能简单地将每个都包装在自己的异常处理程序中吗? 例如:

try
 response1 = ...

catch(Exception e)
 //set some flag here


try
 response2 = ...

catch(Exception e)
 //set some flag here

这样你就知道哪个过去了,哪个没有过去,并根据那个条件设置一些标志,等等。

【讨论】:

以上是关于异步调用中的异常会扰乱执行的主要内容,如果未能解决你的问题,请参考以下文章

WCF 异步调用 - 事件处理程序中的异常

未使用 await 调用时在异步方法中捕获异常

Effective JavaScript Item 63 注意异步调用中可能会被忽略的异常

调用异步任务芹菜时引发异常:“NameError:未定义全局名称*”

[万字详解]JavaScript 中的异步模式及 Promise 使用

异步回调函数