私はそのようなコードを持っています:
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マイクロ秒)保持されます。したがって、別のスレッドに移動するのは得策ではない可能性があります。すべてを同じスレッドで実行する必要があると思います。