【问题标题】:Async task hanging [duplicate]异步任务挂起[重复]
【发布时间】:2017-03-14 19:39:50
【问题描述】:

我有以下代码:

public async Task SendPushNotificationAsync(string username, string message)
{
    var task = ApnsNotifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, username);
    if (await Task.WhenAny(task, Task.Delay(500)) == task) {
       return true;
    }
    return false;
}

我注意到SendAppleNativeNotificationAsync 无限期地挂起(从不返回包含方法),所以我尝试告诉它在 500 毫秒后取消。但仍然......对WhenAny 的调用现在挂起,我从来没有看到return 被击中,导致消费者无限期地等待(这是一个调用此异步方法的同步方法,所以我调用.Wait()):

_commService.SendPushNotificationAsync(user.Username, notificationDto.PushContent).Wait(TimeSpan.FromSeconds(1));

无论如何,我如何强制它在设定的时间后完成?

如果我只是“解雇并忘记”而不是await执行任务会发生什么?

【问题讨论】:

  • 你在哪里执行这段代码?我的意思是,Web 应用程序、桌面应用程序,或者移动设备?
  • @Evk 这是从同步服务方法调用的服务方法中,由 WebApi 控制器调用。
  • 永远不要在带有“UI”或“请求”线程的环境中将 Wait(或 Task.Result)与 async\await 一起使用 - 它会像您观察到的那样死锁。
  • @Evk 是“死锁”还是“阻塞直到完成”?
  • 这是死锁,但我无法在 cmets 中解释的原因,您可以在重复问题中看到它们。

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


【解决方案1】:

这是一个同步方法调用这个异步方法,所以我调用.Wait()

这就是你的问题。你是deadlocking because you're blocking on asynchronous code

最好的解决方案是使用await 而不是Wait

await _commService.SendPushNotificationAsync(user.Username, notificationDto.PushContent);

如果您绝对不能使用await,那么您可以尝试我的Brownfield Async article 中描述的一种技巧。

【讨论】:

  • 谢谢。如果我使用awaitSendAppleNativeNotificationAsync 永远不会返回,我会好吗?
  • @SB2055:为什么它永远不会回来?
  • 我基于我从调试器中看到的行为 - 我永远无法捕捉到 return 但可能是因为另一个线程正在接收它?
  • @SB2055:阻止它会阻止完成。如果你await它,它应该可以正常工作。
  • @StephenCleary 我在异步方法中遇到了这个确切的问题。当设置断点和等待时,下一行代码永远不会在任务挂起的情况下被调用,尽管消息被传递到端点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 2018-06-27
  • 2011-10-05
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 2018-07-05
相关资源
最近更新 更多