【发布时间】:2019-10-21 08:57:35
【问题描述】:
假设我们使用具有真正高速财务数据的网络套接字。在高峰期,网络套接字方法每秒被调用数百到数千次。
我们的网络套接字方法中有一个条件不时变为真。在这种情况下,应该调用另一个方法。但只有一次。由于该方法的执行速度,很难防止重复执行。代码如下所示:
private readonly ConcurrentDictionary<string, bool> _inExecution = new ConcurrentDictionary<string, bool>();
private void SubscribeToSocket()
{
_socket.Connect();
var subscription = SocketSubscriptions.CreateSubsription(data =>
{
Task.Run(async () =>
{
// read data
if (condition)
{
// call method only once
await Execute(key);
condition = false;
}
}
}
}
private async Task Execute(string key)
{
// Even with this statement the code calls are too fast and sometimes gets executed twice
if (!_inExecution[key])
{
_inExecution[key] = true;
// do something..
}
}
我已经尝试在 Execute() 方法之前通过随机等待来防止双重执行。像这样:
if (condition)
{
var rnd = new Random();
await Task.Delay(rnd.Next(15, 115));
// call method only once
await Execute(key);
condition = false;
}
但即使在某些特殊情况下也会执行两次。有没有更好的方法来防止这种情况发生?
【问题讨论】:
-
使用互斥体?或其他并发管理工具:docs.microsoft.com/en-us/dotnet/api/…
-
看起来,正如 Milney 所建议的,您需要某种形式的锁定。试试
SemaphoreSlimstackoverflow.com/a/45769160/1481699 -
注意:SemaphoreSlim 在同步和异步代码的边缘情况下会出现一些讨厌的故障...我有一个 MutexSlim 专门设计用于避免它们,如果它可能会有所帮助......但是,这是一个尖叫某种信号量/互斥体设置的场景
-
@MarcGravell 当然,一切都会有所帮助。您是否有指向其他信息的链接或带有示例代码的 github 存储库?