我尝试启动多线程,但我不能它返回给我错误:跨线程操作无效:'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();
}
答案 0 :(得分:5)
不允许后台线程访问UI组件。
在多线程表单中,我包含如下代码:
private delegate void InvokeAction();
private void DoUI(InvokeAction call) {
if (IsDisposed) {
return;
}
if (InvokeRequired) {
try {
Invoke(call);
} catch (InvalidOperationException) {
// Handle error
}
} else {
call();
}
}
然后从我的后台线程我可以像这样编码:
// Stuff in other thread
myVar = GetFromDb();
DoUI(() => {
// Access UI components here
listBox1.Items.Add(myVar);
});
// More other thread
答案 1 :(得分:4)
无法以正常方式在另一个线程中访问在UI线程中创建的控件。请创建一个委托并使用control.Invoke。
调用委托下面提供的方法示例可用于启用按钮的可见性,而不管您所处的线程上下文。
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);
答案 2 :(得分:3)
您无法从非UI线程更新UI组件。使用TaskScheduler.FromCurrentSynchronizationContext
封送对UI线程的调用。