用于发布的FireAndForget和Async行为之间的差异

时间:2015-08-20 22:26:41

标签: redis stackexchange.redis

目前,我们正在使用StackExchange.Redis,因为它没有提供"阻止弹出广告",我们按照文档中的建议进行操作:

pack configure

与此相比有何不同?

db.ListLeftPush(key, newWork, flags: CommandFlags.FireAndForget);
sub.Publish(channel, "");

我们知道这些命令的目的,我们想知道的是内部是否存在任何差异或是否有任何不同的行为风险? (执行令等)

1 个答案:

答案 0 :(得分:5)

比较 fire和忘记 vs 调用异步操作而不是等待它有一个主要区别。

火灾和遗忘意味着您不仅没有等待结果,而且您​​不关心它是否有效,而异步操作可能会抛出异常一次如果出现问题就结束了。

另一方面,当您发出 fire并忘记命令时,StackExchange.Redis不会尝试在内部检索命令结果,如果您只是想要这样做,那就更好了在发出命令时调用 fire并忘记行为。

如果您打开ConnectionMultiplexer源代码并了解如何实施ExecuteAsyncImpl / ExecuteSyncImpl方法,则可以检查这种差异:

// For example, ExecuteAsyncImpl...
if (message.IsFireAndForget)
{
  TryPushMessageToBridge(message, processor, null, ref server);
  return CompletedTask<T>.Default(null); // F+F explicitly does not get async-state
}
else
{
  var tcs = TaskSource.CreateDenyExecSync<T>(state);
  var source = ResultBox<T>.Get(tcs);
  if (!TryPushMessageToBridge(message, processor, source, ref server))
  {
    ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, message.Command, message, server));
  }

  return tcs.Task;
} 

回答一些OP评论

  

您好。感谢您的回答。我们知道命令的目的,是什么   我们想知道它是否在内部或任何方面存在差异   表现不同的风险(执行顺序等)

由于在Redis频道上发布消息时异步操作不会完成,因此您可能会发布消息并且操作永远不会执行。你失去了很多控制权。

当您发送 fire并忘记命令时,它也可能无法执行,但您知道在发布频道的消息之前已完成尝试。因此,在使用StackExchange.Redis时,您不应该使用异步操作来实现 fire并忘记模式。

您可以查看此其他相关问答:Stackexchange.redis does fire and forget guarantees delivery?