1.对于在子线程操作Ui控件需要返回到ui线程上操作,如果这操作量很大,界面不卡也是难事。2.推荐使用backgroudworker控件,很标准的一个ui线程和子线程交互的一个控件

解决方案 »

  1.   

    不管是Invoke或者是BeginInvoke作用都是能回到控件对应线程执行操作。BeginInvoke其实还跟EndInvoke对应。
    你这个需求条例说得不清楚~~无法理解……for(int i=0;i<100;i++){
    ThreadPool.QueueUserWorkItem((obj) =>
    {
       // 在线程中做耗时的操作,这样就不会造成界面卡死的现象。
        int index = (int)obj;
        Label label = new Label();
        label.Font = new Font("宋体", rd.Next(1, 16) + rd.Next(0, 10) * 0.1F, FontStyle.Regular, GraphicsUnit.Pixel, (byte)134);
        label.Location = new Point(x, y);
        label.Size = new Size(80, 23);
        label.Text = index.ToString();
        x = 5 + (index % numX) * 85;
        y = 5 + (index / numX) * 25;    this.BeginInvoke(new Action(() =>
        {
            // 最后再调用异步回调UI线程添加控件。
            this.Controls.Add(label);
        }));
    }
    }
      

  2.   

    根据我个人的理解和使用Invoke\BeginInvoke的感受:其实他们的实质还是把控制权交回给了主线程,所以如果线程耗时较长的话,界面还是会有假死现象...
      

  3.   

    我想在主线程中新建一个线程创建一个窗口,然后在这个窗口里面有个datagridview,我要在里面动态添加行,我不需要修改主界面的UI控件,其中我这个线程是在主界面的一个for循环下面写的,而我这个for循环是写在一个定时器里面的
      

  4.   

    假设我已经理解你的意思,嘿嘿:// Form1窗体
    private void timer1_Tick(object sender, EventArgs e)
    {
        for (int i = 0; i < 1; i++)
        {
            new Thread(() =>
            {
                 // 启动线程为Form2加载数据
                frm2.LoadData(this.GetDataTable());
            }).Start();
        }
    }在Form2中public void LoadData(DataTable data)
    {
        // 从刚才的代码看出这里应该还是处于Timer所开的线程中
        dataGridView1.Invoke(new Action<DataTable>((dt) =>
        {
            // 加载数据。
            dataGridView1.DataSource = dt;
        }), data);
    }
    而最后想说的是如果这样会导致界面卡的话,应该是数据太多,DataGridView在加载的时候会卡住。考虑下分页显示之类的。
    或者使用Dev的GridControl也能加载大数据。
      

  5.   

    你没明白同步跟异步跟线程的问题。
    同步跟异步只是在执行的时间点不同而已,两者都是在同一个线程的,所以在这里同步做了会卡死的异步也会。这里要解决你这个问题是,如何在线程中加载数据(但不刷新),然后回调到主线程刷新(数据一多可能刷新还是会卡)。
    DataGridView相当于你一赋值DataSource就会触发Invalidate事件,然后刷新,而数据量大的情况这个过程就会很长。这里它自己涉及到UI控件的调用,所以需要在对应的UI线程。试试这个?DataGridView 加载大数据
      

  6.   

    你没明白同步跟异步跟线程的问题。
    同步跟异步只是在执行的时间点不同而已,两者都是在同一个线程的,所以在这里同步做了会卡死的异步也会。这里要解决你这个问题是,如何在线程中加载数据(但不刷新),然后回调到主线程刷新(数据一多可能刷新还是会卡)。
    DataGridView相当于你一赋值DataSource就会触发Invalidate事件,然后刷新,而数据量大的情况这个过程就会很长。这里它自己涉及到UI控件的调用,所以需要在对应的UI线程。试试这个?DataGridView 加载大数据异步不是要多线程同时处理?
      

  7.   

    添加个窗口方法private void AddRow(object arg)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new Action<object>((object arg1) => {
                this.AddRow(arg1);
            }), arg);
        }
        else
        {
            // TODO: AddRow
        }
    }