通过遍历,创建了多线程,即一个线程里面创建一个label,并向一个list里面添加一次数据,创建所有的线程完成后,遍历list,读取list的数据,做成下拉单的情况,但是没反应,我调试的时候发现创建线程的时候,list的数据也是有的,但是遍历list的时候,list就没有数据了,求大神指导!!!
这是load的代码:  private void frmMain_Load(object sender, EventArgs e)
        {
            EQ2008Config.GetSection();
            string strpath = AppDomain.CurrentDomain.BaseDirectory + "\\StationConfig.xml";
            XmlDocument doc = new XmlDocument();//初始化一个xml实例
            doc.Load(strpath);//导入指定的xml文件
            XmlNode no = doc.SelectSingleNode("StationList");//指定一个节点
            XmlNodeList listnode = no.SelectNodes("StationData");//获取同名同级别"stationdata"节点集合
            
            ti = new TimerCallback(ShowDataToScreenStation);
            //System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            foreach (XmlNode node in listnode)//遍历所有的stationdata节点
            {                //Set_labelText(node);
                weituo = new WeiTuo<XmlNode>(Set_labelText);
                //wt = new WT_test(Test);
                StartThread(node);
               
            }
            //生成已经包含的检查站的下拉菜单
            foreach (StationData m in Program.listStationList)//这里在完成上面的遍历后,Program.listStationList没数据
            {
                ToolStripMenuItem msta = new ToolStripMenuItem(m.StatinName);
                msta.Tag = m.StatinName;
                msta.Click += new EventHandler(新增检测站ToolStripMenuItem_Click);
                this.检测站参数设置ToolStripMenuItem.DropDownItems.Add(msta);
            }
            this.timRefreshData_Tick(null, null);            开始发送正常数据ToolStripMenuItem_Click(null, null);
            FileInfo f = new FileInfo("StationConfig.xml");
            iStartDateXmlOLD = f.LastWriteTime.Ticks;
            f = new FileInfo("EQ2008_Dll_Set.ini");
            iIntDatexmlOLD = f.LastWriteTime.Ticks;            this.timer1.Enabled = true;
        }线程的相关代码: public void Set_labelText(XmlNode strText) 
        {
            this.Invoke((Action<XmlNode>)delegate(XmlNode node)
            {
                StationData stationData = new StationData(node);
                //stationData.IsShow = false;
                Program.listStationList.Add(stationData);
                this.flowLayoutPanel1.BackColor = Color.Orange;
                Label lab = new Label();//实例一个label显示                lab.Name = "lab" + stationData.CardFlagID.ToString();
                lab.AutoSize = false;
                lab.Size = new Size(280, 140);
                lab.BorderStyle = BorderStyle.Fixed3D;
                lab.Text = stationData.StatinName;
                lab.Font = new Font("宋体", 11);                if (stationData.IsShow)
                {
                    lab.BackColor = Color.Green;
                }
                if (stationData.IsShow)
                {
                    System.Threading.Timer tim = new System.Threading.Timer(ti, stationData.CardFlagID, 0, 10000);
                    //超过0秒后,以及此后每隔10秒间隔,都会调用一次由TimerCallback(ShowDataToScreenStation)指定的委托。
                    dicThread.Add(stationData.CardFlagID.ToString(), tim);                }
                this.flowLayoutPanel1.Controls.Add(lab);
            }, strText);
        }
        /// <summary>
        /// 通过调用委托,来添加label里面的值
        /// </summary>
 private void Run(XmlNode s) 
        {
            weituo.Invoke(s);
        }
        
        /// <summary>
        /// 创建线程方法 
        /// </summary>
void StartThread(XmlNode x)
        {
            new Thread(() => Set_labelText(x)).Start();
        }list遍历线程thread多线程

解决方案 »

  1.   

    Run()方法和weituo = new WeiTuo<XmlNode>(Set_labelText);这句
    和那几个委托都可以删掉了 = =上张贴不是说了么,多线程是异步执行的,你直接遍历list取不到数据也很正常;
    线程启动后就开始遍历list了,而不是线程执行完后才遍历list、同步和异步你要分清楚
      

  2.   

    你遍历list的时候,并不能保证你的线程已经开始填充数据了 ,因为是异步,不等线程填充也会继续执行后续代码,所以你要同步你的操作,保证线程填充完毕后,在去遍历
      

  3.   

    嗯,懂了,真是学习了,我这个是一个监测站一个线程也就是label,如果同步的话,会和异步有什么区别,烦劳给解释一下,谢谢了!
      

  4.   

    写了个例子,不过有点乱,你参考下
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Threading;namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            FlowLayoutPanel flPanel;
            ManualResetEvent[] ManualArray;
            public Form1()
            {
                InitializeComponent();
                flPanel = new FlowLayoutPanel() { Dock = DockStyle.Fill };
                this.Controls.Add(flPanel);
                ManualArray = new ManualResetEvent[10];
                this.Load += new EventHandler(Form1_Load);
            }        void Form1_Load(object sender, EventArgs e)
            {
                for (int i = 0; i < 10; i++)
                {
                    ManualArray[i] = new ManualResetEvent(false);
                    ThreadPool.QueueUserWorkItem(new WaitCallback(AddBtn), new State(i, ManualArray[i]));
                }            //开一条新的线程,等待线程执行完后加载下拉列表
                new Thread(delegate()
                    {
                        WaitHandle.WaitAll(ManualArray);       //这里会一直等待所有线程执行完后才会往下走
                        MessageBox.Show("所有线程执行完成!"); //这里开始加载下拉列表
                    }).Start();        }        void AddBtn(object obj)
            {
                State state = (State)obj;
                this.Invoke((Action<int>)delegate(int i)
                {
                    flPanel.Controls.Add(new Button() { Text = i.ToString() });
                }, state.Num);
                state.manualResetEvent.Set();
                Thread.Sleep(5000);             //为了让效果看起来明显,每次执行完睡5秒
            }
        }    class State
        {
            public int Num;
            public ManualResetEvent manualResetEvent;        public State(int Num, ManualResetEvent manualResetEvent)
            {
                this.Num = Num;
                this.manualResetEvent = manualResetEvent;
            }
        }
    }
      

  5.   

     不带这样玩的吧,代码都给你了,你只需要把你原来的改下就行了;本来多线程的地方你就用线程池,加载下拉列表的地方你就多开一条线程、然后再加个State类,看着改就行了
      

  6.   

    已经有了,就是在加载下拉列表哪里开个监控线程,这样吧,你源码发我邮箱 [email protected] 一会我给你看看