假设一个GUI(C#,WinForms)执行工作并且忙了几秒钟。它仍然会有需要保持可访问的按钮,会改变的标签,进度条等等。
我现在正在使用这种方法在忙时更改GUI:
//Generic delegates
private delegate void SetControlValue<T>(T newValue);
//...
public void SetStatusLabelMessage(string message)
{
if (StatusLabel.InvokeRequired)
StatusLabel.BeginInvoke(new SetControlValue<string>(SetStatusLabelMessage, object[] { message });
else
StatusLabel.Text = message;
}
我一直在使用它,因为它已经过时了,但我不太确定这是否合适。创建委托(并重新使用它)使整个事情更清洁(至少对我而言),但我必须知道我不是在创造一个怪物......
答案 0 :(得分:6)
另一种方法是在需要更新GUI时使用BackgroundWorker并使用ReportProgress。这将为您处理Invoke,以便您不必担心它。
答案 1 :(得分:2)
此处的最佳做法是使用BackgroundWorker运行长时间运行的任务。它是专为WinForms设置的特殊线程类,仅用于此目的。您可以将工作发送给它,取消它,并让它将消息发送回WinForm线程以更新状态。基本上,通过使用BackgroundWorker,您的GUI可以保持自由和活动状态。
答案 2 :(得分:2)
其他人已经提到使用BackgroundWorker来运行你的工作。这就是你在做什么的?
在任何情况下,如果您想知道从后台线程更新UI的最佳方法是什么,您正在做的事情看起来很好,尽管我建议使用Invoke
而不是BeginInvoke
。此外,您可以使用MethodInvoker
来简化代码,而不是声明自己的单独代理:
StatusLabel.Invoke(new MethodInvoker(delegate() { /* Update control here */ }));
答案 3 :(得分:1)
看起来对我来说。只要你将这种东西封装到自己经过良好测试的类中,就应该没有问题。