我有一個在.NET Winforms中編碼的項目。 我需要執行數據挖掘操作,將文本打印到TextBox並更新進度。.NET BackGroundWorker - InvalidOperationException:跨線程操作無效
我試圖用BackgroundWorker的做的,但它拋出一個InvalidOperationException異常(跨線程操作無效:控制「XXXXX」從比它是在創建的線程以外的線程訪問)
要縮小我開始了一個新項目,其中包括以下內容: 按鈕 - 啓動BackgroundWorker 標籤 - 打印文本。 和ProgressBar。
但是,結果是一樣的。我搜索了特種部隊,並被告知使用代表,但我不熟悉它。
這是引發錯誤的代碼示例:
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace TestProject
{
public partial class Form1 : Form
{
private readonly BackgroundWorker _bw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
_bw.DoWork += RosterWork;
_bw.ProgressChanged += BwProgressChanged;
_bw.RunWorkerCompleted += BwRunWorkerCompleted;
_bw.WorkerReportsProgress = true;
_bw.WorkerSupportsCancellation = false;
}
private void RosterWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
for (int i = 0; i < 1000; i++)
{
label1.Text = i.ToString();
_bw.ReportProgress(Convert.ToInt32((i * (100/1000))));
}
}
private void BwProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void btnStart_Click(object sender, EventArgs e)
{
progressBar1.Show();
_bw.RunWorkerAsync();
}
private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Hide();
}
}
}
更新: 我跟喬恩飛碟雙向的答案,它真的在我的測試項目工作,但回到我真正的項目,
我的佈局形式:
表 - 的TabControl - TAB1 -Tab1Panel -TextBox1
當達到這一行:
TextBox txtbox1 = new TextBox();
Tab1Panel.Controls.Add(txtbox1);
的錯誤,當我添加文本框到面板控制編程仍時有發生。
最後,我代替這個:
if (Tab1Panel.InvokeRequired)
Tab1Panel.Invoke((MethodInvoker)delegate { Tab1Panel.Controls.Add(txtbox1); });
else
Tab1Panel.Controls.Add(txtbox1);
一切工作。如何確定控件是InvokeRequired,它是否指定了控件?
謝謝喬恩斯基特!我在Google上搜索.NET Threading。我讀了一些關於Thread/ThreadStart/ThreadPool/Delegate的文章。看起來它們都更像預期的線程編程標準。那麼使用BackgroundWorker是否正確? – Cheung
你的意思是「哪一個不是**在UI線程上運行」? – Geoff
@Geoff:是的,謝謝。 –