WinForn程序,窗口加载时,向窗体中的三个ComboBox控件绑定数据源,并设置DisplayMember和ValueMember属性.
数据源大于10万条记录.打开窗体Very慢.等待时间大于7秒.最要命的是窗口卡住.必需加载完成才可用..遂采用多线程..
以下为代码片断.. public delegate void SetValueDisplayDelegate(); public void StartSet()
{
//为三个ComboBox绑定数据源..方法已经封装.此处调用.
SaleBind.BindSaleProduct(cbBoxProductID, cbBoxProductName, cbBoxBarCode);
//创建线程1
Thread productIDThread = new Thread(new ThreadStart(DoneProductID));
productIDThread.Name = "ProductID";
productIDThread.SetApartmentState(ApartmentState.STA);
productIDThread.Start();
//创建线程2
Thread productNameThread = new Thread(new ThreadStart(DoneProductName));
productNameThread.Name = "ProductName";
productNameThread.SetApartmentState(ApartmentState.STA);
productNameThread.Start();
//创建线程3
Thread barCodeThread = new Thread(new ThreadStart(DoneBarCode));
barCodeThread.Name = "BarCode";
barCodeThread.SetApartmentState(ApartmentState.STA);
barCodeThread.Start();
}
private void DoneProductID()
{
cbBoxProductID.Invoke(new SetValueDisplayDelegate(SetProductIDMapping));
} private void DoneProductName()
{
cbBoxProductName.Invoke(new SetValueDisplayDelegate(SetProductNameMapping));
} private void DoneBarCode()
{ cbBoxBarCode.Invoke(new SetValueDisplayDelegate(SetBarCodeMapping));
} //经查证,绑定数据源只需1秒,慢的原因在于指定DisplayMember 和ValueMember .
private void SetProductIDMapping()
{
cbBoxProductID.DisplayMember = "ProductID";
cbBoxProductID.ValueMember = "ProductID";
cbBoxProductID.AutoCompleteSource = AutoCompleteSource.ListItems;
cbBoxProductID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
} private void SetProductNameMapping()
{
cbBoxProductName.DisplayMember = "ProductName";
cbBoxProductName.ValueMember = "ProductID";
cbBoxProductName.AutoCompleteSource = AutoCompleteSource.ListItems;
cbBoxProductName.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
} private void SetBarCodeMapping()
{
cbBoxBarCode.DisplayMember = "BarCode";
cbBoxBarCode.ValueMember = "ProductID";
cbBoxBarCode.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
cbBoxBarCode.AutoCompleteSource = AutoCompleteSource.ListItems;
}
//启用了一个后台进程.
private void backgroundWorkerMain_DoWork(object sender, DoWorkEventArgs e)
{
StartSet();
}
//窗口加载事件
private void FormSale_Load(object sender, EventArgs e)
{
backgroundWorkerMain.RunWorkerAsync();
}
}经查证,绑定数据源只需1秒,慢的原因在于指定DisplayMember 和ValueMember .为什么?
另外,调试发现,3个线程都停在了各自的创建委托代码块..事实是,是主线程在执行全部代码..昏中...
求优化解决方案..
数据源大于10万条记录.打开窗体Very慢.等待时间大于7秒.最要命的是窗口卡住.必需加载完成才可用..遂采用多线程..
以下为代码片断.. public delegate void SetValueDisplayDelegate(); public void StartSet()
{
//为三个ComboBox绑定数据源..方法已经封装.此处调用.
SaleBind.BindSaleProduct(cbBoxProductID, cbBoxProductName, cbBoxBarCode);
//创建线程1
Thread productIDThread = new Thread(new ThreadStart(DoneProductID));
productIDThread.Name = "ProductID";
productIDThread.SetApartmentState(ApartmentState.STA);
productIDThread.Start();
//创建线程2
Thread productNameThread = new Thread(new ThreadStart(DoneProductName));
productNameThread.Name = "ProductName";
productNameThread.SetApartmentState(ApartmentState.STA);
productNameThread.Start();
//创建线程3
Thread barCodeThread = new Thread(new ThreadStart(DoneBarCode));
barCodeThread.Name = "BarCode";
barCodeThread.SetApartmentState(ApartmentState.STA);
barCodeThread.Start();
}
private void DoneProductID()
{
cbBoxProductID.Invoke(new SetValueDisplayDelegate(SetProductIDMapping));
} private void DoneProductName()
{
cbBoxProductName.Invoke(new SetValueDisplayDelegate(SetProductNameMapping));
} private void DoneBarCode()
{ cbBoxBarCode.Invoke(new SetValueDisplayDelegate(SetBarCodeMapping));
} //经查证,绑定数据源只需1秒,慢的原因在于指定DisplayMember 和ValueMember .
private void SetProductIDMapping()
{
cbBoxProductID.DisplayMember = "ProductID";
cbBoxProductID.ValueMember = "ProductID";
cbBoxProductID.AutoCompleteSource = AutoCompleteSource.ListItems;
cbBoxProductID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
} private void SetProductNameMapping()
{
cbBoxProductName.DisplayMember = "ProductName";
cbBoxProductName.ValueMember = "ProductID";
cbBoxProductName.AutoCompleteSource = AutoCompleteSource.ListItems;
cbBoxProductName.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
} private void SetBarCodeMapping()
{
cbBoxBarCode.DisplayMember = "BarCode";
cbBoxBarCode.ValueMember = "ProductID";
cbBoxBarCode.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
cbBoxBarCode.AutoCompleteSource = AutoCompleteSource.ListItems;
}
//启用了一个后台进程.
private void backgroundWorkerMain_DoWork(object sender, DoWorkEventArgs e)
{
StartSet();
}
//窗口加载事件
private void FormSale_Load(object sender, EventArgs e)
{
backgroundWorkerMain.RunWorkerAsync();
}
}经查证,绑定数据源只需1秒,慢的原因在于指定DisplayMember 和ValueMember .为什么?
另外,调试发现,3个线程都停在了各自的创建委托代码块..事实是,是主线程在执行全部代码..昏中...
求优化解决方案..
在线程里 循环一行一行的添加.在循环里使用Application.DoEvents(); 看看.
我觉得应该是在主线程中(也就是循环外)使用 Application.DoEvents() : //启用了一个后台进程.(这应该是后台线程吧?)
private void backgroundWorkerMain_DoWork(object sender, DoWorkEventArgs e)
{
StartSet(); while (后台线程.IsAlive)
{
Application.DoEvents();
} }
invoke和begininvoke的调用,实际上也是让UI线程来做的,所以在工作线程上直接使用invoke意思就不大了,
应该如下
// workThread
TODO: 耗时的操作
TODO: invoke以上嵌套在循环也行,只在invoke不要调用得太频繁,UI界面就不太死住了顺便
4楼正解 刚刚在机器上测试了下, 即使不使用多线程操作,只需要在for循环里调用DoEvents就可以实现楼主希望实现的功能
你的绑定是把所有的数据都读入了内存吧?
要看封装的实现了,这个设计本身就存在这个缺陷,不管你用不用线程。
因为ComboBox这个控件的内部UI消息一定是在主线程进行处理的,这个是UI的工作。不管.net如何封装,目前依然依赖Windows底层的实现。
在SDK的程度上理解这个问题就知道了,ComboBox的很多操作都是通过消息来控制。如果你想优化,需要改变你的绑定设计思路,当一个数据源存在大量记录的时候,绑定不应当把左右的数据都加载,你需要优化你的数据源访问方式,而不是UI的部分
你的绑定是把所有的数据都读入了内存吧?
要看封装的实现了,这个设计本身就存在这个缺陷,不管你用不用线程。
因为ComboBox这个控件的内部UI消息一定是在主线程进行处理的,这个是UI的工作。不管.net如何封装,目前依然依赖Windows底层的实现。
在SDK的程度上理解这个问题就知道了,ComboBox的很多操作都是通过消息来控制。 如果你想优化,需要改变你的绑定设计思路,当一个数据源存在大量记录的时候,绑定不应当把左右的数据都加载,你需要优化你的数据源访问方式,而不是UI的部分
up
2、如果是连动显示数据,也应该只将符合条件的筛选出来,而不是加载全部数据。
if(InvokedRequst)//自己查
{
beginInvoke(参数);
}
else
{
你要执行的操作!;
}
而不是放在_DoWork(object sender, DoWorkEventArgs e)里面,放在里面相当于4个线程一起执行