我有这样的代码:
public void TablesUpdated(object sender, TablesUpdatedArgs args)
{
lock (quotesLock)
{
while (!args.quotesQueue.IsNullOrEmpty())
quotes.Enqueue(args.quotesQueue.Dequeue());
}
lock (securitiesLock)
{
while (!args.securitiesUpdates.IsNullOrEmpty())
securities.Enqueue(args.securitiesUpdates.Dequeue());
}
lock (orderUpdatesLock)
{
while (!args.orderUpdates.IsNullOrEmpty())
orderUpdates.Enqueue(args.orderUpdates.Dequeue());
}
}
这段代码的问题是我正在等待,lock
而我可能会处理代码的其他部分。在我等待期间,代码的其他部分可能会被锁定!
假设quotesLock
在 0 到 1 秒securitiesLock
之间忙,在 1 到 2 秒orderUpdatesLock
之间忙,在 2 到 3 秒之间忙。由于订单,我的代码将完全被阻止 3 秒。
但如果qoutesLock
将是最后一个:
public void TablesUpdated(object sender, TablesUpdatedArgs args)
{
lock (securitiesLock)
{
while (!args.securitiesUpdates.IsNullOrEmpty())
securities.Enqueue(args.securitiesUpdates.Dequeue());
}
lock (orderUpdatesLock)
{
while (!args.orderUpdates.IsNullOrEmpty())
orderUpdates.Enqueue(args.orderUpdates.Dequeue());
}
lock (quotesLock)
{
while (!args.quotesQueue.IsNullOrEmpty())
quotes.Enqueue(args.quotesQueue.Dequeue());
}
}
代码将在 1 秒内执行。
问题是如何重写代码:
- 如果无法获取某些锁,则正在处理其他锁
- 没有创建额外的线程(因为那太昂贵了)。
while
可能我应该用很多方法编写非常复杂的循环TryEnter
。或者什么会更好?
在现实中, upd锁定的时间很短(大约 5-15 微秒)。所以转到另一个线程可能不是一个好主意,我认为一切都应该在同一个线程中完成。