在C#winform中线程化以显示启动画面错误 [英] Threading in C# winform to show a splash screen ERROR
本文介绍了在C#winform中线程化以显示启动画面错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
大家好,
我试图显示启动画面,但显示以下错误:
< b>跨线程操作无效:控制'cmbEnviroment'从其创建的线程以外的线程访问
这是我的线程代码:
private void LoadInstitutions()
{
//Thread.Sleep(3000);
// OperationClass oc = new OperationClass();
// oc.loading();
string selectedValue = cmbEnviroment.SelectedItem.ToString()。Trim();
ConnectionClass connectionClass = new ConnectionClass();
connectionClass.Connection(selectedValue);
DataTable table4 = new DataTable();
string sql4 =收集数据的查询;
try
{
OleDbDataAdapter da4 = new OleDbDataAdapter(sql4,connectionClass.Connection(selectedValue));
da4.Fill(table4);
DataRow dr4 = table4.NewRow();
DataRow dr5 = table4.NewRow();
dr4 [hello1] =;
table4.Rows.InsertAt(dr4,0);
cmbInstitution.DataSource = table4;
cmbInstitution.DisplayMember =hello1;
cmbInstitution.ValueMember =hello1;
}
catch(exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private async void cmbEnviroment_SelectedIndexChanged(object sender,EventArgs e)
{
//使用(new PleaseWait(this.Location))
// {
ComboBox senderComboBox =(ComboBox)sender;
if(senderComboBox.SelectedIndex> 0)
{
LoadingScreen ls = new LoadingScreen();
ls.TopMost = true;
ls.Show();
await Task.Run(()=> LoadInstitutions());
ls.Close();
}
//}
}
我尝试了什么:
我尝试了不同的方法来显示启动画面,而我正在从数据库收集数据但是我卡住了。
解决方案
你无法从UI线程以外的任何线程访问任何控件 - 当你尝试时,你会看到一个交叉线程异常。
解决此问题的两种方法:
1)调用控件而不是直接访问它: Control.Invoke方法(委托)(System.Windows.Forms) [ ^ ]
2)移动使用BackgroundWorker类将长时间运行的代码放入后台线程,后者旨在向UI线程提供进度信息以进行更新。
重构代码以将长时间运行的部分移动到后台线程,并保留在UI线程上访问UI的部分:
私有 静态 DataTable LoadInstitutions( string selectedValue)
{
ConnectionClass connectionClass = new ConnectionClass();
const string sql = 收集数据的查询;
DataTable result = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter(sql,connectionClass.Connection(selectedValue));
da.Fill(结果);
DataRow dr = result.NewRow();
dr [ hello1] = ;
result.Rows.InsertAt(dr, 0 );
返回结果;
}
private async 任务LoadInstitutions()
{
尝试
{
string selectedValue = cmbEnviroment.SelectedItem的ToString()修剪();
DataTable table = await Task.Run(()= > LoadInstitutions(selectedValue)) ;
cmbInstitution.DataSource = table4;
cmbInstitution.DisplayMember = hello1;
cmbInstitution.ValueMember = hello1;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
私有 async void cmbEnviroment_SelectedIndexChanged( object sender,EventArgs e)
{
ComboBox senderComboBox =(ComboBox)发件人;
if (senderComboBox.SelectedIndex > 0 )
{
LoadingScreen ls = new LoadingScreen();
ls.TopMost = true ;
ls.Show();
尝试
{
await LoadInstitutions();
}
最后
{
ls.Close();
}
}
}
Hi guys ,
im trying to show splash screen but the following error is shown:
Cross-thread operation not valid: Control 'cmbEnviroment' accessed from a thread other than the thread it was created on
this is my code for the threading :
private void LoadInstitutions() { //Thread.Sleep(3000); // OperationClass oc = new OperationClass(); // oc.loading(); string selectedValue = cmbEnviroment.SelectedItem.ToString().Trim(); ConnectionClass connectionClass = new ConnectionClass(); connectionClass.Connection(selectedValue); DataTable table4 = new DataTable(); string sql4 = "A query to gather data"; try { OleDbDataAdapter da4 = new OleDbDataAdapter(sql4, connectionClass.Connection(selectedValue)); da4.Fill(table4); DataRow dr4 = table4.NewRow(); DataRow dr5 = table4.NewRow(); dr4["hello1"] = ""; table4.Rows.InsertAt(dr4, 0); cmbInstitution.DataSource = table4; cmbInstitution.DisplayMember = "hello1"; cmbInstitution.ValueMember = "hello1"; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private async void cmbEnviroment_SelectedIndexChanged(object sender, EventArgs e) { //using (new PleaseWait(this.Location)) //{ ComboBox senderComboBox = (ComboBox)sender; if (senderComboBox.SelectedIndex > 0) { LoadingScreen ls = new LoadingScreen(); ls.TopMost = true; ls.Show(); await Task.Run(() => LoadInstitutions()); ls.Close(); } //} }
What I have tried:
im have tried different methods to show the splash screen while i'm gathering data from database but im stuck .解决方案You cannot access any control from any thread other than the UI thread - when you try, you get a "cross thread exception" as you are seeing.
Two ways to fix this:
1) Invoke the control instead of accessing it directly: Control.Invoke Method (Delegate) (System.Windows.Forms)[^]
2) Move your long running code into a background thread using the BackgroundWorker class which is designed to provide progress information to the UI thread for updates.
Refactor your code to move the long-running part to a background thread, and keep the parts that access the UI on the UI thread:
private static DataTable LoadInstitutions(string selectedValue) { ConnectionClass connectionClass = new ConnectionClass(); const string sql = "A query to gather data"; DataTable result = new DataTable(); OleDbDataAdapter da = new OleDbDataAdapter(sql, connectionClass.Connection(selectedValue)); da.Fill(result); DataRow dr = result.NewRow(); dr["hello1"] = ""; result.Rows.InsertAt(dr, 0); return result; } private async Task LoadInstitutions() { try { string selectedValue = cmbEnviroment.SelectedItem.ToString().Trim(); DataTable table = await Task.Run(() => LoadInstitutions(selectedValue)); cmbInstitution.DataSource = table4; cmbInstitution.DisplayMember = "hello1"; cmbInstitution.ValueMember = "hello1"; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private async void cmbEnviroment_SelectedIndexChanged(object sender, EventArgs e) { ComboBox senderComboBox = (ComboBox)sender; if (senderComboBox.SelectedIndex > 0) { LoadingScreen ls = new LoadingScreen(); ls.TopMost = true; ls.Show(); try { await LoadInstitutions(); } finally { ls.Close(); } } }
这篇关于在C#winform中线程化以显示启动画面错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文