簡體   English   中英

在C#中使用backgroundworker時,跨線程操作無效

[英]Cross thread operation not valid when use backgroundworker in c#

  private bool ImportData()
        {   
            bool result = false;
         try
            {

                      intdevid = int.Parse(cmbDeviceName.SelectedValue.ToString());
                         FetchDevicedata(intdevid);


                    //FTPTCompletedBatchTransfer();
                    FetchMaxReportId();

                    GetFTPFile(strDeviceIP, strDeviceUsername, strDevicePwd, strDevicePath + "//RunningBatch//RunningBatch.db", "RunningBatch.db"); // Copy RunningBatch.db to Debug Folder from Remote 
                    LoadRunningData(); // Get Running Data in dataset from running.db
                    if (DecodeBatchData_R() == false)
                    {

                        MessageBox.Show("Running Batch Data Not Found");


                    }// save in batch master and row data table

                    GetFTPFile(strDeviceIP, strDeviceUsername, strDevicePwd, strDevicePath + "//CompletedBatch//CompletedBatch.db", "CompletedBatch.db");
                    LoadCompletedData();
                    if (DecodeBatchData() == false)
                    {

                        MessageBox.Show("Completed Batch Data not found");

                    }
                    result = true;

                }



            catch (Exception ex)\\here error:Cross-thread operation not valid: Control 'cmbDeviceName' accessed from a thread other than the thread it was created on.
            {
                clsLogs.LogError("Error: " + ex.Message + this.Name + " || ImportData");
                result = false;

            }



            return result;
        }
    private void btnimport_Click(object sender, EventArgs e)
    {
         //////////////////copy checkweigher .db to database folder
        dsCheckRptId = new DataSet();
        ///////////////////////////////////////////////////////////
        if (cmbDeviceName.Text.ToString().Trim() == "--Select--")
        {
            MessageBox.Show("Please Select Proper Device");
            cmbDeviceName.Focus();
            return;
        }
        var deviceId = (int)cmbDeviceName.SelectedValue;
        bgw.RunWorkerAsync(deviceId);
        progressBar1.Visible = true;
        label2.Visible = true;



    }
    void bgw_DoWork(object sender, DoWorkEventArgs e)
    {

        for (int i = 1; i <= 100; i++)
        {
            var deviceId = (int)e.Argument;
            e.Result = ImportData();
            System.Threading.Thread.Sleep(100);
            bgw.ReportProgress(i);

        }
    } 

    void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
        label2.Text = String.Format("Progress: {0} %", e.ProgressPercentage);
    }

    void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var result = (bool)e.Result;
        if (cmbDeviceName.SelectedValue != null && cmbDeviceName.SelectedValue.ToString().Trim() != "0" && cmbDeviceName.SelectedValue.ToString().Trim() != "System.Data.DataRowView" && cmbDeviceName.SelectedValue.ToString().Trim() != "")

          if (result)
        {
            MessageBox.Show("Data Import Completed Successfully for " + strDevicename);
            clsLogs.LogEvent(3, "Data Import Completed Successfully for " + strDevicename);
        }
        else
        {
            MessageBox.Show("Data Import Fail For " + strDevicename);
            clsLogs.LogEvent(3, "Data Import Fail for " + strDevicename);
        }    
        progressBar1.Visible = false;
        label2.Visible = false;
    }

;當我運行此后台工作程序編碼時,出現錯誤,指出“跨線程操作無效:從創建該線程的線程之外的其他線程訪問控件'cmbDeviceName'。

我該如何解決這個問題?

WinForms控件不是線程安全的,因此控件上的跨線程操作無效。 您只能從創建這些控件的線程訪問控件。 在您的代碼中,您正在從后台線程訪問cmbDeviceName組合框。 解決此問題的最佳方法是將intdevid作為RunWorkerAsync參數傳遞:

// executed on main thread
var deviceId = (int)cmbDeviceName.SelectedValue;
backgroundWorker.RunWorkerAsync(deviceId);

並在您的DoWork處理程序中獲取此參數:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
   // executed on background thread
   var deviceId = (int)e.Argument;

   // ...
}

建議閱讀: Windows窗體中的安全,簡單多線程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM