异步加载数据,方法2和4造成界面假死,方法3造成DataGridView滚动条不可用,那位大侠能帮我解决一下。
public FrmDbAsyn()
{
    InitializeComponent();
    Control.CheckForIllegalCrossThreadCalls = false;
}private void btn_Click(object sender, EventArgs e)
{
    /* 1、数据量多,界面不能动
    RefreshTable();*/    /* 假死 
    frmLoad frm = new frmLoad("加载");
    frm.Action = RefreshTable;
    frm.ShowDialog();*/    /* 2、实例委托,加载数据完成以后假死 
    AsyncEventHandler asy = new AsyncEventHandler(RefreshTable);
    // 异步调用开始,没有回调函数和AsyncState,都为null
    IAsyncResult ia = asy.BeginInvoke(new AsyncCallback(FinishAction), asy);*/    /* 3、多线程加载,DataGridView滚动条不可用 
    Thread th = new Thread(new ThreadStart(RefreshTable));
    th.IsBackground = true;
    th.Start();*/    /* 4、使用BackgroundWorker,和2一样 */
    BackgroundWorker bgwWorker = new BackgroundWorker();
    bgwWorker.WorkerReportsProgress = true;
    //开始执行后台操作時
    //当执行BackgroundWorker.RunWorkerAsync方法时会触发该事件,并且传递DoWorkEventArgs参数;
    bgwWorker.DoWork += new DoWorkEventHandler(bgwWorker_DoWork);
    //引发 ProgressChanged 事件。 ProgressChanged是负责报告当前程序进度
    bgwWorker.ProgressChanged += new ProgressChangedEventHandler(bgwWorker_ProgressChanged);
    //当后台操作已完成、被取消或引发异常时发生。
    bgwWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgwWorker_RunWorkerCompleted);
    bgwWorker.RunWorkerAsync(); 
    
}private void FinishAction(IAsyncResult ar)
{
    AsyncEventHandler async = (AsyncEventHandler)ar.AsyncState;
    if (async != null)
    {
        async.EndInvoke(ar);
        async = null;
        Application.DoEvents();
    }
}#region BackgroundWorkerprivate void bgwWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{}private void bgwWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{}private void bgwWorker_DoWork(object sender, DoWorkEventArgs e)
{
    RefreshTable();
}#endregionprivate void RefreshTable()
{
    // 耗时操作,在操作的过程中,有对界面控件的操作,如更新界面显示状态等
    DataTable dt = GetList();
    gv.DataSource = dt;
}

解决方案 »

  1.   

    先试着在refreshTable()的循环中添加
    Application.DoEvents();
    看看有没有效果。
      

  2.   

    添加上述方法,在处理RefreshTable的过程中会响应一些界面的消息,改善操作。
    原则上我觉得你的方法还是应该使用 Thread,但你说没有滚动条,是否由于在操作的过程中未能正确的刷新Grid的行数信息导致它没有正确刷新。
      

  3.   

    BackgroundWorker 对于多线程不是理想的方法,而且还需要使用委托来解决
      //建立个委托 
    private delegate string returnStrDelegate(); 
     
    //搞个最简单滴取值滴方法~ 
    private string returnSchool() 
          { 
               return CB_School.SelectedValue.ToString(); 
          } 
     
    //判断一下是不是该用Invoke滴~,不是就直接返回~ 
    private string returnCB(returnStrDelegate myDelegate) 
           { 
              if (this.InvokeRequired) 
               { 
                   return (string)this.Invoke(myDelegate); 
               } 
              else 
                { 
                   return myDelegate(); 
                } 
            } ,建议还是手动写Thread,BackgroundWorker 不是为多线程而设计的.
      

  4.   

    在RefreshTable()的循环中添加 
    Application.DoEvents(); 
    还是一样,会假死。
    使用Thread,大数据量的dt直接赋值给gv的DataSource,不知你说的“未能正确的刷新Grid的行数信息”该如何正确刷新。
      

  5.   

    建议使用一个一步操作机制类处理,并显示有好进度提示,类似实现可以参照这里,
    http://blog.csdn.net/zhzuo/archive/2008/07/23/2699305.aspx
      

  6.   

        最后是怎么解决的啊楼主?我是一菜鸟麻烦大侠指点指点啊。。我这边是一设置datagridview 的scorllbars属性,界面进行tcp/ip异步通信的时候就会假死、怎么解决啊?
      

  7.   

     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            }        private void button1_Click(object sender, EventArgs e)
            {
                Thread Tt = new Thread(new ThreadStart(DoThreadTo));
                Tt.Start();
            }
            private void DoThreadTo()
            {
                for (int i = 0; i < 99999999; i++)
                {
                    dataGridView1.Refresh();// RefreshTable();
    Application.DoEvents();
                    dataGridView1.Rows.Add("11", "22", "33");
                }
            }
        }
      

  8.   

    如果想滚动条好用,用跨线程
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    namespace APP
    {
        public partial class Form1 : Form
        {
            Thread TH = null;
            public delegate void SetTextCallback(DataGridView label, params object[] text);
            public Form1()
            {
                InitializeComponent();
              //  System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            }
            /// <summary>
            /// 跨线程调用控件
            /// </summary>
            /// <param name="label">Label控件</param>
            /// <param name="text">准备赋的值</param>
            private void DataGridViewRowAdd(DataGridView labelView, params object[] Rowtext)
            {
                if (labelView.InvokeRequired)
                {
                    SetTextCallback method = new SetTextCallback(this.DataGridViewRowAdd);
                    base.Invoke(method, new object[] { labelView, Rowtext });
                }
                else
                {
                    labelView.Rows.Add(Rowtext);
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                TH = new Thread(new ThreadStart(DoWork));
                TH.Start();
            }
            public void DoWork()
            {
                for (int i = 0; i <= 999999999; i++)
                {                //dataGridView1.Rows.Add(i.ToString(),"bb","cc");
                    //dataGridView1.Refresh();
                    //Application.DoEvents();
                    DataGridViewRowAdd(dataGridView1, i.ToString(), "bb", "cc");
                }
                TH.Abort();
             
            }        private void button2_Click(object sender, EventArgs e)
            {
                TH.Abort();
                Application.DoEvents();
            }
        }
    }
      

  9.   

    为啥不在 backgroundworker 事件里面更新界面?