如何解决“跨线程操作无效”?

时间:2021-09-09 02:33:49

i try to start multi Thread but i can not it returns to me error: Cross-thread operation not valid: 'listBox1' thread was created to control outside access from another thread was.

我尝试启动多线程,但我不能它返回给我错误:跨线程操作无效:'listBox1'线程被创建,以控制从另一个线程的外部访问。

MyCodes:

 
  public DataTable dTable;
        public DataTable dtRowsCount;
        Thread t1;
        ThreadStart ts1;
  void ExcelToSql()
        {
           // SelectDataFromExcel();
            ts1 = new ThreadStart(SelectDataFromExcel);
            t1 = new Thread(ts1);
            t1.Start();
        }
   void SelectDataFromExcel()
        {
            string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Source\Addresses.xlsx;Extended Properties=""Excel 12.0;HDR=YES;""";
            OleDbConnection excelConnection = new OleDbConnection(connectionString);
                      string[] Sheets = new string[] { "Sayfa1"};
            excelConnection.Open(); // This code will open excel file.            
            OleDbCommand dbCommand;
            OleDbDataAdapter dataAdapter;
          //  progressBar1.Minimum = 1;

            foreach (var sheet in Sheets)
            {
                dbCommand = new OleDbCommand("select * From[" + sheet + "$]", excelConnection);
                //progressBar1.Maximum = CountRowsExcel(sheet).Rows.Count;
               // progressBar2.Value = i + 1;
                System.Threading.Thread.Sleep(1000);
                **listBox1.Items.Add("Tablo ismi: "+sheet.ToUpper()+"Satır Adeti: "+CountRowsExcel(sheet).Rows.Count.ToString()+" ");**
                dataAdapter = new OleDbDataAdapter(dbCommand);
                dTable = new DataTable();
                dataAdapter.Fill(dTable);
                dTable.TableName = sheet.ToUpper();
                dTable.Dispose();
                dataAdapter.Dispose();
                dbCommand.Dispose();
                ArrangedDataList(dTable);
                FillSqlTable(dTable, dTable.TableName);
            }

            excelConnection.Close();
            excelConnection.Dispose();
        }

3 个解决方案

#1


5  

The thread in background is not allowed to access the UI components.

后台中的线程不允许访问UI组件。

In multithreaded forms, I include code like this:

在多线程表单中,我包含如下代码:

    private delegate void InvokeAction();
    private void DoUI(InvokeAction call) {
        if (IsDisposed) {
            return;
        }
        if (InvokeRequired) {
            try {
                Invoke(call);
            } catch (InvalidOperationException) {
                // Handle error
            }
        } else {
            call();
        }
    }

Then from my background thread I can code like this:

然后从我的后台线程我可以像这样编码:

    // Stuff in other thread
    myVar = GetFromDb();
    DoUI(() => { 
       // Access UI components here 
       listBox1.Items.Add(myVar);
    });
    // More other thread 

#2


4  

A control created in the UI thread cannot be accessed in another thread in normal fashion. Please create a delegate and invoke the delegate using control.Invoke.

无法以正常方式在另一个线程中访问在UI线程中创建的控件。请创建一个委托并使用control.Invoke调用委托。

The method sample provided below can be used to enable visibility on a button regardless of the thread context you are in.

下面提供的方法示例可用于启用按钮的可见性,而不管您所处的线程上下文。

private void EnableButtonVisibility( Button btn, bool enable)    
{     
    if ( !btn.InvokeRequired )    
    {    
 btn.Visible = enable;    
    }   
    else    
    {    
        btn.Invoke( new EnableButtonVisibilityHandler( EnableButtonVisibility ), btn, enable );    
    }    
}    
delegate void EnableButtonVisibilityHandler( Button btn, bool enable);

#3


3  

You cannot update a UI component from a non-UI thread. Use TaskScheduler.FromCurrentSynchronizationContext to marshal the call to the UI thread.

您无法从非UI线程更新UI组件。使用TaskScheduler.FromCurrentSynchronizationContext封送对UI线程的调用。

#1


5  

The thread in background is not allowed to access the UI components.

后台中的线程不允许访问UI组件。

In multithreaded forms, I include code like this:

在多线程表单中,我包含如下代码:

    private delegate void InvokeAction();
    private void DoUI(InvokeAction call) {
        if (IsDisposed) {
            return;
        }
        if (InvokeRequired) {
            try {
                Invoke(call);
            } catch (InvalidOperationException) {
                // Handle error
            }
        } else {
            call();
        }
    }

Then from my background thread I can code like this:

然后从我的后台线程我可以像这样编码:

    // Stuff in other thread
    myVar = GetFromDb();
    DoUI(() => { 
       // Access UI components here 
       listBox1.Items.Add(myVar);
    });
    // More other thread 

#2


4  

A control created in the UI thread cannot be accessed in another thread in normal fashion. Please create a delegate and invoke the delegate using control.Invoke.

无法以正常方式在另一个线程中访问在UI线程中创建的控件。请创建一个委托并使用control.Invoke调用委托。

The method sample provided below can be used to enable visibility on a button regardless of the thread context you are in.

下面提供的方法示例可用于启用按钮的可见性,而不管您所处的线程上下文。

private void EnableButtonVisibility( Button btn, bool enable)    
{     
    if ( !btn.InvokeRequired )    
    {    
 btn.Visible = enable;    
    }   
    else    
    {    
        btn.Invoke( new EnableButtonVisibilityHandler( EnableButtonVisibility ), btn, enable );    
    }    
}    
delegate void EnableButtonVisibilityHandler( Button btn, bool enable);

#3


3  

You cannot update a UI component from a non-UI thread. Use TaskScheduler.FromCurrentSynchronizationContext to marshal the call to the UI thread.

您无法从非UI线程更新UI组件。使用TaskScheduler.FromCurrentSynchronizationContext封送对UI线程的调用。