异步加载数据,方法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;
}
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;
}
Application.DoEvents();
看看有没有效果。
原则上我觉得你的方法还是应该使用 Thread,但你说没有滚动条,是否由于在操作的过程中未能正确的刷新Grid的行数信息导致它没有正确刷新。
//建立个委托
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 不是为多线程而设计的.
Application.DoEvents();
还是一样,会假死。
使用Thread,大数据量的dt直接赋值给gv的DataSource,不知你说的“未能正确的刷新Grid的行数信息”该如何正确刷新。
http://blog.csdn.net/zhzuo/archive/2008/07/23/2699305.aspx
{
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");
}
}
}
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();
}
}
}