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'是从其创建的线程以外的线程访问的。”
如何解决这个问题呢?
答案 0 :(得分:1)
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;
// ...
}