在C#winform中线程化以显示启动画面错误 [英] Threading in C# winform to show a splash screen ERROR

查看:76
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆