【问题标题】:Timeout in Async Method异步方法超时
【发布时间】:2018-05-21 08:42:45
【问题描述】:

我有一个名为“RequestMessage()”的异步方法。在此方法中,我将向消息代理发送消息。因为我不知道什么时候可以期待结果,所以我使用“TaskCompletionSource”。我希望异步方法在回复消息到达时终止(我将从代理收到一个事件)。

到目前为止,这工作正常。现在,我的问题是这条消息永远无法得到答复,或者至少为时已晚。

我正在寻找一种改变来实现我自己的超时。为此,我尝试了一个计时器,以及反应式扩展的观察者。问题总是一样的 - 我无法让我的主线程和计时器线程同步,因为我使用的是 .NET Core 2 并且没有 SynchronizationContext。

所以,在我的代码中有一个观察者..

        Observable
        .Interval(TimeSpan.FromSeconds(timeOutInSeconds))
        .Subscribe(
            x =>
            {
                timeoutCallback();
            });

如果时间到期,则应调用回调。在我的调用者方法中,我以这种方式处理回调:

    TimeoutDelegate timeoutHandler = () => throw new WorkcenterRepositoryCommunicationException("Broker communication timed out.", null);

正如您已经意识到的那样,这个异常永远不会被捕获,因为它不会被抛出到主线程。

如何在此处同步线程?

提前致谢!

【问题讨论】:

  • 如何向代理发送消息?客户端?还有什么?

标签: c# asynchronous async-await timeout asp.net-core-2.0


【解决方案1】:

“在某些问题上失败”恕我直言,最好的方法是抛出适当的异常,但你绝对可以只使用 return;如果您希望避免异常。

这将创建一个同步完成的已完成/错误任务,因此使用 await 的调用者将获得已完成的任务并继续使用同一线程。

CancellationToken 允许调用者取消操作,您所描述的情况并非如此。 Task.Yield 不会终止任何操作,它只是让其他任务运行一段时间并重新安排自己以供以后使用。

【讨论】:

  • 谢谢。如果我要从计时器的范围内抛出异常,它将被抛出到不同的线程中。同样的问题 IMO。
  • 您可以在此处查看另一个线程中的异常处理:stackoverflow.com/questions/5983779/…
猜你喜欢
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 2011-04-22
相关资源
最近更新 更多