FireAndForget 和异步发布行为之间的区别
Difference between FireAndForget and Async behavior for publishing
目前,我们正在使用 StackExchange.Redis,并且由于它不提供 "blocking pops",我们正在按照文档中的建议进行操作:
db.ListLeftPush(key, newWork, flags: CommandFlags.FireAndForget);
sub.Publish(channel, "");
这个和下面的有什么区别?
db.ListLeftPushAsync(key, newWork);
sub.Publish(channel, "");
我们知道这些命令的目的,我们想知道的是它在内部是否有任何差异或行为不同的风险? (执行顺序等)
比较 fire and forget 与 调用异步操作而不等待它.
有一个主要区别
即发即弃意味着你不仅不等待结果而且你不关心它是否有效,而异步操作可能会抛出异常如果出现问题,一旦结束。
另一方面,当您发出 fire and 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;
}
对一些 OP 评论的回答
Hi. Thanks for your answer. We know the purpose of the commands, what
we would like to know is if it has any differrence internally or any
risk of behaving differently (execution order etc.)
由于当您在 Redis 通道上发布消息时异步操作不会完成,因此可能会发生您发布消息而操作永远不会执行的情况。你失去了很多控制。
当您发送 fire and forget 命令时,它可能不会被执行,但您知道在发布频道消息之前尝试已经完成。因此,在使用 StackExchange.Redis.
时,不应使用异步操作来实现 fire and forget 模式
您可以查看其他相关问答:Stackexchange.redis does fire and forget guarantees delivery?
目前,我们正在使用 StackExchange.Redis,并且由于它不提供 "blocking pops",我们正在按照文档中的建议进行操作:
db.ListLeftPush(key, newWork, flags: CommandFlags.FireAndForget);
sub.Publish(channel, "");
这个和下面的有什么区别?
db.ListLeftPushAsync(key, newWork);
sub.Publish(channel, "");
我们知道这些命令的目的,我们想知道的是它在内部是否有任何差异或行为不同的风险? (执行顺序等)
比较 fire and forget 与 调用异步操作而不等待它.
有一个主要区别即发即弃意味着你不仅不等待结果而且你不关心它是否有效,而异步操作可能会抛出异常如果出现问题,一旦结束。
另一方面,当您发出 fire and 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;
}
对一些 OP 评论的回答
Hi. Thanks for your answer. We know the purpose of the commands, what we would like to know is if it has any differrence internally or any risk of behaving differently (execution order etc.)
由于当您在 Redis 通道上发布消息时异步操作不会完成,因此可能会发生您发布消息而操作永远不会执行的情况。你失去了很多控制。
当您发送 fire and forget 命令时,它可能不会被执行,但您知道在发布频道消息之前尝试已经完成。因此,在使用 StackExchange.Redis.
时,不应使用异步操作来实现 fire and forget 模式您可以查看其他相关问答:Stackexchange.redis does fire and forget guarantees delivery?