我是多线程的新手(有点初学者/中级程序员),所以我可能会遗漏一些非常明显的东西。我目前正在开发一个应用程序,它必须从服务器(确切地说是bloomberg服务器)中提取数据,并且还运行业务逻辑。
要从服务器中提取数据,您基本上必须运行无限循环才能不断刷新数据。目前,所有数据拉取代码/逻辑都在一个单独的类中,并且具有许多公共对象(下面的代码中的dataDict),它们使用最新数据进行更新。
我的想法是在一个单独的线程上运行程序的数据拉动部分,并让其余的业务逻辑在主线程上运行。然后,只要业务逻辑需要最新数据,它就可以从另一个线程(字典)中调用数据对象。关于下面的代码,我希望该类在后台运行并让主业务逻辑选择Dictionary,Object> dataDict在需要时。我真的不确定如何最好地做到这一点。
我尝试使用BackgroundWorker,但我遇到的问题是因为循环无穷无尽我永远无法触发RunWorkerCompleted事件处理程序,并且DoWork处理程序将被过早调用(数据需要一些时间)完全下载)。
任何帮助都将非常感谢!!
为了说明程序的一部分,datapull的代码是(注意,我必须进行一些编辑,因此大括号/括号可能不完美):
class BloombergSync
{
private Session mainSession = new Session();
private List<String> contracts = new List<string>();
private List<String> fields = new List<string>();
public List<String> safeContracts = new List<string>();
public List<String> safeFields = new List<string>();
public Dictionary<Tuple<string, string>, Object> dataDict = new Dictionary<Tuple<string, string>, object>();
private BackgroundWorker worker = new BackgroundWorker();
{
while (true)
{
try
{
Event eventObj = mainSession.NextEvent();
foreach (Message msg in eventObj.GetMessages())
{
if (eventObj.Type == Event.EventType.SUBSCRIPTION_DATA)
{
Element dataElement = msg.AsElement;
//Figures out which contract the data is in reference to.
string topic = msg.TopicName;
// Then must add the data to the appropriate contract and field.
foreach (string field in fields)
{
if (dataElement.HasElement(field, true))
{
// Collects data for the field
Element elm = dataElement.GetElement(field);
var dataPoint = elm.GetValue();
// Have to figure out how to select first topic, and then the field within that topic. Has
// two keys (first topic, then field).
Tuple<string, string> tuple = new Tuple<string, string>(topic, field);
dataDict[tuple] = dataPoint;
worker.ReportProgress(1);
}
}
}
else
{
//Do Nothing if not data
}
}
}
catch (Exception ex)
{
System.Console.WriteLine("Got Exception:" + ex);
}
}
}
答案 0 :(得分:7)
听起来像producer-consumer
个情景。您需要一个thread-safe
对象(在您的情况下是一个队列)来传输数据。
在.NET 4.0
中有一个System.Collections.Concurrent
thread-safe
,您可以在项目中使用。然后,后台工作人员可以将数据放入CuncurrentQueue
,而消费者可以将数据项出列。