【发布时间】:2010-03-04 05:55:48
【问题描述】:
我正在编写一个 C# Windows 窗体应用程序,该应用程序通过算法(策略)处理来自市场的报价,从而为经纪公司创建订单。这一切似乎都测试得相当好,直到我尝试建立在其自己的线程上同时运行多个策略的能力。此时一切都开始运行不正确。我相信我有一些不是线程安全的类,它们会导致不稳定的行为。任何关于我如何以线程安全的方式线程化的见解都非常感谢!
报价输入算法的方式如下: 1) 市场数据事件从 Brokers Software 触发到我的软件中名为 ConnectionStatus 的客户端类。当触发市场数据事件时,会根据这些静态变量的当前值构建一个 Quote 对象,这些静态变量代表 Bid、ask 等。 一旦报价建立,我会努力将其发送到每个正在运行的策略算法中。这是我用来执行此操作的代码:
foreach (StrategyAssembler assembler in StrategyAssembleList.GetStrategies())
{
BackgroundWorker thread = strategyThreadPool.GetFreeThread();
if (thread != null)
{
thread.DoWork += new DoWorkEventHandler(assembler.NewIncomingQuote);
thread.RunWorkerAsync(quote);
}
}
StrategyAssembler 是一个创建类 StrategyManager 实例的类,该类又创建一个包含实际算法的策略实例。可能有 4 或 6 个不同的 StrategyAssembler 实例,每个实例都被添加到 StrategyAssembleList 的 Singleton 实例中,该实例是一个 BindingList。
传入的报价对象被传递到 StrategyAssembler 类的 NewIncomingQuote 方法中。该代码如下:
public void NewIncomingQuote(object sender, DoWorkEventArgs e)
{
Quote QUOTE = e.Argument as Quote;
lock (QuoteLocker)
{
manager.LiveQuote(QUOTE);
priorQuote = QUOTE;
}
}
我在想,通过在将报价传递给 manager.LiveQuote(Quote quote) 方法之前使用锁,所有使用报价“下游”的对象都可以在线程安全中使用报价时尚,但测试显示并非如此。有没有一种方法可以将 StrategyAssembler 的每个实例放在它自己的线程上,以确保 Strategy Assembler 创建的所有对象都是线程安全的,然后将引用提供给 StrategyAssembler?这种思维方式是否适合处理这种情况?
提前感谢您的任何反馈或帮助,
学习1
【问题讨论】:
-
1)
manager.LiveQuote()做什么?它是您的策略方法的接口吗? 2)QuoteLocker是StrategyAssembler实例成员吗? 3) 最后,你期待什么样的行为,你看到了什么? -
1) manager.Livequote() 是 a) 将报价添加到由指标类和策略算法类和 OrderFill 模拟类引用的列表中 b) 将报价传递到 StrategyAlgorithm 的方法c)管理Strategy中的订单对象,模拟订单填写/取消/通信延迟等。
-
2) QuoteLocker 是一个静态对象 static object QuoteLocker = new object();
-
3) 在行为方面,我希望每个报价在到达时被添加到 StrategyAssembler 的每个实例中,并从那里添加到 manager.LiveQuote。从那里,该策略通过其算法来决定买入/卖出/什么也不做。每个 Assembler 实例只有 1 个 StrategyManager 实例,每个 StrategyManager 实例只有 1 个策略类,用于传递报价和管理订单。我看到的行为是将单引号添加到给定的汇编器实例 1 或 2 或 3 或 4 次,而根本没有添加到不同的汇编器实例
-
这些建议对你有用吗?
标签: c# multithreading threadpool