C# - 多线程,一个线程运行无限循环

时间:2010-12-30 19:29:31

标签: c# multithreading thread-safety backgroundworker

我是多线程的新手(有点初学者/中级程序员),所以我可能会遗漏一些非常明显的东西。我目前正在开发一个应用程序,它必须从服务器(确切地说是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);
            }

        }
    }

1 个答案:

答案 0 :(得分:7)

听起来像producer-consumer个情景。您需要一个thread-safe对象(在您的情况下是一个队列)来传输数据。

.NET 4.0中有一个System.Collections.Concurrent thread-safe,您可以在项目中使用。然后,后台工作人员可以将数据放入CuncurrentQueue,而消费者可以将数据项出列。