目前,我们正在使用StackExchange.Redis,因为它没有提供“阻止弹出窗口”,我们按照文档中的建议进行操作:
db.ListLeftPush(key, newWork, flags: CommandFlags.FireAndForget);
sub.Publish(channel, "");
这与以下有什么不同?
db.ListLeftPushAsync(key, newWork);
sub.Publish(channel, "");
我们知道命令的目的,我们想知道的是内部是否存在任何差异,或者表现出不同的行为风险? (执行令等)
比较fire和forget与调用异步操作而不是等待它有一个主要区别。
火与遗忘意味着你不仅没有等待结果,而且你不关心它是否有效,而异步操作一旦出现问题就可能抛出异常。
另一方面,当您发出fire和forget命令时,StackExchange.Redis不会尝试在内部检索命令结果,如果您只是想在发出命令时想要所谓的fire and forget行为,那就更好了。
如果打开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;
}
你好。感谢您的回答。我们知道命令的目的,我们想知道的是内部是否存在任何差异,或者是否有任何不同的行为风险(执行顺序等)
由于在Redis通道上发布消息时无法完成异步操作,因此您可能会发布消息并且操作永远不会执行。你失去了很多控制权。
当您发送fire and forget命令时,它可能也不会被执行,但您知道在发布频道消息之前已完成尝试。因此,在使用StackExchange.Redis时,不应使用异步操作来实现fire和forget模式。
您可以查看其他相关的问答:Stackexchange.redis does fire and forget guarantees delivery?