我正在尝试在后台工作进程中更改表单上的标签但是它表示未处理的异常。我看了一下这个错误,它说要调用它就像接受的答案一样:Update label text in background worker winforms
我已经成功地改变了复选框列表中的值,但是我使用了相同的方法,并且对于它不会调用的标签,我在键入时在代码中得到红色错误行。
我的背景工作者:
private void bw2_DoWork(object sender, DoWorkEventArgs args)
{
BackgroundWorker worker = sender as BackgroundWorker;
func.sshConnect();
for (int num = 0; num < checklist.Items.Count; num++)
{
if (checklist.GetItemChecked(num))
{
string project = checklist.Items[num].ToString();
lblStatus.Text = "Opening " + project + "..."; //error here
if (func.svnCheckoutProject(project))
{
lblStatus.Text = project + " Opened"; //same error here
func.sshRunCommand("echo " + project + " >> " + Properties.Settings.Default.serverUserFilesPath + Properties.Settings.Default.Username);
}
else
{
//error message
}
}
worker.ReportProgress(num * (100 / checklist.Items.Count));
}
}
我已经尝试用这个替换错误的行,但是在visual studio中它在调用时给它一个红线并且不允许我构建它。
lblStatus.Invoke((MethodInvoker)delegate { lblStatus.Text = "Opening " + project + "..."; });
当错误出现时,Visual Studio将我指向此处:MSDN我使用此方法作为复选框列表并且它可以工作但是尝试用于标签并且它不起作用。
任何关于它为什么不起作用或其他方式的想法?
不要从DoWork
事件更新UI控件 - 您在UI线程的单独线程上。你可以调用Invoke,但它确实不适合它。
BackgroundWorker
已经提供了一个构造,用于在工作者运行时定期更新UI线程,并且您已经在使用它 - 它是ReportProgress
方法。那是你应该更新你的标签的地方。其中的任何内容都会在主UI线程上运行。
你可以将你想要的任何object
传递给ReportProgess
方法:
worker.ReportProgress(num * (100 / checklist.Items.Count),
string.Format("Opening {0} ...", project));
然后将值转换回来并在ProgressChanged
事件中使用它:
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var message = e.UserState.ToString();
lblStatus.Text = message;
}
在大多数情况下,您可能希望使用BeginIvoke而不是Invoke
public void changeLabelText(System.Windows.Forms.Label lib, String whateva)
{
if (lib.InvokeRequired)
{
lib.BeginInvoke(new MethodInvoker(() => changeLabelText(lib, whateva)));
}
else
{
lib.Text = whateva;
}
}
并在DoWork中调用该方法
private void bw_DoWork(object sender, DoWorkEventArgs args)
{
//do something
//change the text of a label lb1
changeLabelText(lb1, "I'm reporting some progress....");
}