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

key*_*oss 1 c# multithreading backgroundworker thread-safety

我是多线程的新手(有点初学者/中级程序员),所以我可能会遗漏一些非常明显的东西.我目前正在开发一个应用程序,它必须从服务器(确切地说是bloomberg服务器)中提取数据,并且还运行业务逻辑.

要从服务器中提取数据,您基本上必须运行无限循环来不断刷新数据.目前,所有数据拉取代码/逻辑都在一个单独的类中,并且具有许多公共对象(下面的代码中的dataDict),它们使用最新数据进行更新.

我的想法是在一个单独的线程上运行程序的数据拉动部分,并让其余的业务逻辑在主线程上运行.然后,只要业务逻辑需要最新数据,它就可以从另一个线程(字典)中调用数据对象.关于下面的代码,我希望该类在后台运行,并让主业务逻辑在需要时选择Dictionary,Object> dataDict.我真的不确定如何最好地做到这一点.

我尝试使用BackgroundWorker,但我遇到的问题是,因为循环无穷无尽,我永远无法触发RunWorkerCompleted事件处理程序,并且DoWork处理程序将很快被调用(数据完全下载需要一些时间) .

任何帮助将非常感激!!

为了说明程序的一部分,数据随机的代码是(注意,我必须进行一些编辑,因此大括号/括号可能不完美):

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);
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)

Xaq*_*ron 7

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

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