【问题标题】:Debugging Task.WhenAny and Push Notifications调试 Task.WhenAny 和推送通知
【发布时间】:2017-08-27 11:17:42
【问题描述】:

我有以下 sn-p 来处理 Azure 通知中心推送通知:

var alert = "{\"aps\":{\"alert\":\"" + message + "\"}}";

var task = AzurePushNotifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, username);

if (await Task.WhenAny(task, Task.Delay(500)) == task)
{
     success = true;
}

有时,这会失败 - 我正在尝试找出原因?

在使用Task.WhenAny 运行事物时,获取一些诊断信息的最佳方式是什么?

我想知道是否引发了异常,或者是否已达到超时。

【问题讨论】:

  • 这个失败是什么意思?如果超时,您只为通知分配了 500 毫秒,这可能需要增加。如果您await 单独通知任务会引发异常吗?如果是这样,请发布这些详细信息。
  • 你为什么不只是等待任务;任务.Wait();然后查看TaskResult task.TaskResult?
  • @JSteward 有时我会收到success = false。这要么是因为它没有在 500 毫秒内完成,要么是因为抛出了异常。我想知道其中哪一个正在发生。如果是异常,我想知道异常是什么。如果它需要> 500ms,我希望它失败,但我想知道这就是它失败的原因。如果没有这些超时,推送通知有时会持续很长时间。
  • @MichaelPuckettII 见上述评论

标签: c# .net azure async-await azure-notificationhub


【解决方案1】:

你基本上有三种可能:

  1. Task.WhenAny(task, Task.Delay(500)) == task 是假的。表示任务超时
  2. Task.WhenAny(task, Task.Delay(500)) == task 是真的。然后:
    • 如果t1.Status == TaskStatus.RanToCompletion,则任务运行成功
    • 否则,它要么被取消,要么出现故障。查看task.IsFaultedtask.Exception 了解更多信息

如果需要 > 500 毫秒,我希望它失败,但我想知道这就是它失败的原因

在这种情况下,您唯一能知道的就是通知超时了。由于任务尚未完成,因此没有异常记录。如果你想在它最终完成时检查状态,你可以链接一个延续:

task.ContinueWith(t => 
{
    // Log t.Exception
}, TaskContinuationOptions.OnlyOnFaulted);

【讨论】:

  • 虽然逻辑是正确的,但我不能容忍ContinueWith/IsFaulted/Exception 的这种用法。您应该只使用 await 代替:await taskif 块内。
  • @StephenCleary 如果我们使用 await 那么它首先会破坏超时的意义。这里的逻辑是说“好的,任务没有及时响应,所以我将控制权交还给调用者,但我链接了一个延续,以了解任务最终完成时发生了什么”
【解决方案2】:

我想知道是否引发了异常,或者是否已达到超时。

你只需要观察完成的任务,如下:

var task = ...;
if (await Task.WhenAny(task, Task.Delay(500)) == task)
{
  await task;
  success = true;
}

这将传播异常,允许您区分任务失败(将引发异常)、任务成功 (success == true) 和任务超时 (success == false)。

【讨论】:

  • 谢谢斯蒂芬 - 你看到上面凯文的评论了吗?我试图避免请求超过 500 毫秒(即使这很荒谬),并且出于某种原因,这些对通知中心的调用永远不会返回。我已经实施了一个慷慨的超时来解决这个问题,但我想知道 - 你会推荐什么?
  • @user666:我没有使用通知中心的经验,但如果您确定您不是 blocking further up your call stack,那么这将是一个 Azure 技术支持问题。
  • 我从一般编码的角度提出了更多问题 - 如果我 await 某些东西永远无法返回,那么实现上述目标的最佳方法是什么,并在接受的答案?我觉得未来的读者可以从这里得到你的答案中受益——这似乎是异步/等待的一个不太边缘的情况
  • @user666:然后我会让他们修复它,或者写一个替代品。不起作用的代码不能被重用。在这种特殊情况下,没有合适的方法来处理永无止境的任务。框架里什么都没有。没有什么是你自己可以做的。除非您对资源泄漏感到满意,否则只需使用我的答案中的代码即可。
  • @user666: 这么说吧:你有一个泄露资源的函数,你在问如何防止它泄露资源。唯一可能的解决方案是修复它不使用它。我同情,但您要求的是逻辑上的不可能性。如果任务永远不会完成,接受的答案将泄漏资源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 2013-04-17
相关资源
最近更新 更多