【问题标题】:How to cancel a Request/Response communication with a CancellationToken in MassTransit ESB?如何在 MassTransit ESB 中取消与 CancellationToken 的请求/响应通信?
【发布时间】:2016-07-15 10:59:46
【问题描述】:

我有一个简单的公共交通请求/响应概念证明。它由两个应用程序组成:一个用于消息发送,另一个用于消息消费。 消息发送应用程序是这样的:

var basicClient=_busControl.CreateRequestClient<IRequest,IResponse>(queueUri, timeout);
return await basicClient.Request(new Request(json), token);

Request 方法将CancellationToken 作为第二个可选参数。

消息消费者有如下代码:

public async Task Consume(ConsumeContext<IRequest> context)
{
      var outputJson = await _longRunningJob.Execute(context.Message.Input, context.CancellationToken);
      context.Respond(new Response(outputJson));
}

我们可以看到ConsumeContext 也有一个CancellationToken 字段。

所以问题是:我如何使用这些令牌?

在我的消息发送应用程序中,我想取消等待响应, 在消息消费者中,我想取消等待_longrunningJob 完成。

  1. 当我尝试将令牌传递给Request 方法,然后在我的CancellationTokenSource 上调用Cancel() 时,我希望该方法会抛出OperationCancelledException,但我只是得到了响应!
  2. 我也尝试将已取消的令牌传递给此方法,但没有任何反应。
  3. 然后我查看了 Masstransit 的源代码,发现 token.ThrowIfCancellationIsRequested() 没有在任何地方调用!

所以,请告诉我,我在这里做错了什么吗?还有另一种处理 CancellationTokens 的方法,还是只是 Masstransit 的错误?

【问题讨论】:

  • 你需要抛出那个“token.ThrowIfCancellationIsRequested()”,否则你的异步任务永远不会知道,无论是否取消。
  • 在请求者中你可以指定一个超时时间,我认为这比使用取消令牌更好。不确定消费者,它只是您长时间运行的任务的常规异步/等待,与 MassTransit 无关。我不确定消费者的取消令牌是否对请求者有任何请求。我认为通知请求者消费者发生了某些事情的正确方法是发送适当的响应消息,而不是使用技术细节。
  • @x... 我不需要调用该方法,但我认为 MassTransit 应该。
  • @AlexeyZimarev:为什么使用超时比使用取消令牌更好?它们用于不同的原因,我想知道,当用户只需按下 UI 中的“取消”按钮时,你如何使用超时。
  • @DanielVygolov 当用户点击“取消”时,我会正确处理它并将其返回到我的响应消息中。这是业务的一部分,无需涉及技术问题。

标签: c# masstransit cancellation


【解决方案1】:

传递给Request的CancellationToken是取消请求本身,它没有传递给Consumer。

我们设法使用以下方法取消了消费者:

  1. 将到期日期标头添加到请求(UtcNow + 超时)
  2. 在消费者中将 ExpiryDate 标头与 UtcNow 进行比较,如果它较旧则退出该方法

【讨论】:

    猜你喜欢
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 2019-03-09
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    相关资源
    最近更新 更多