我正在查看一些试图解决问题的框架代码。
在此框架中,有两种方法是事件驱动的并且不受我们控制。
我们希望尽可能避免触发关闭事件时执行“ AnalyzeMarket()”方法。
从OnTick()方法调用AnalyzeMarket()方法,该方法在每次引入新价格时发生。这是 超出我们的控制范围。另外,Positions_Closed()方法也是我们无法控制的,因为我们永远不知道什么时候该位置 平仓,不能停止平仓。
下面是我们提供的基本代码段,但100%的时间无法正常运行。我们了解这一点,因为我们显然不知道 什么会引起CPU的关注。
示例:
是否有更好的方法来完成我们要实现的目标?
以下是相关代码段:
//Called by the framework whenever someone closes a price position
private void Positions_Closed(PositionClosedEventArgs args)
{
//Flag so we don't place any more orders or anything until this method completes
_wasClosingEventFired = true;
//other stuff this method does
//Signal that this method is over with
_wasClosingEventFired = false;
}
//This method is called by the framework every time a new price comes in
//This is unpredictable and could be 1ms from "now", 2 seconds from "now", etc.
protected override void OnTick()
{
AnalyzeMarket();
}
private void AnalyzeMarket()
{
//Does a few preliminary logging and other set ups
if (!_wasClosingEventFired)
{
//Does the brunt of the work
//This is the code we want to make sure doesn't
//run when a closing event happens. If that means
//we have to wait a few "ticks", that's fine.
}
//Clean up stuff
}
谢谢。
答案 0 :(得分:0)
我假设这些事件来自不同的线程,这为您带来了竞争条件。我认为,处理这种竞争情况的最简单方法是使用Monitors
语句形式的lock
:
private object sync= new object();
//Called by the framework whenever someone closes a price position
private void Positions_Closed(PositionClosedEventArgs args)
{
lock (sync) {
//other stuff this method does
}
}
//This method is called by the framework every time a new price comes in
//This is unpredictable and could be 1ms from "now", 2 seconds from "now", etc.
protected override void OnTick()
{
AnalyzeMarket();
}
private void AnalyzeMarket()
{
//Does a few preliminary logging and other set ups
lock (sync) {
//Does the brunt of the work
//This is the code we want to make sure doesn't
//run when a closing event happens. If that means
//we have to wait a few "ticks", that's fine.
//Clean up stuff
}
}
这是通过一次只允许一个线程进入监视器(lock(sync) {' enters the monitor and leaves it at the corresponding
}`来实现的。如果一个线程具有锁,则另一个线程将在尝试获得锁之前阻塞,直到获得它为止。
但是,请注意,如果这些操作发生在同一线程上,则需要像原来一样在_wasClosingEventFired
中添加检查,但要在lock语句中。
此外,如果您在这些回调中执行async ... await模式,则不能use lock() { }
包围异步代码。在这种情况下,请使用SemaphoreSlim
作为异步友好的互斥量。