我偶然发现了专业库中的一些代码,并且不确定这是否是一种处理跨线程事件调用的简洁方法.
下面的代码在表单应用程序中.线程调用是从一个本身启动新线程并接收消息的类中进行的:
private void Library_StatusChanged(object sender, AbstractTestCase.StatusChangedEventArgs e)
{
if (this.InvokeRequired)
{
this.lblProgress.Invoke((MethodInvoker)delegate ()
{
lblProgress.Text = "Current state: " + e.Step;
lblProgress.Refresh();
}
);
this.pbProgess.Invoke((MethodInvoker)delegate ()
{
pbProgess.Value = e.Percentage;
pbProgess.Refresh();
});
this.lstStatus.Invoke((MethodInvoker)delegate ()
{
lstStatus.Items.Add(" " + e.Step);
lstStatus.Refresh();
});
this.Invoke((MethodInvoker)delegate ()
{
this.Refresh();
});
}
else
{
lblProgress.Text = "Current state:" + e.Step;
lblProgress.Refresh();
pbProgess.Value = e.Percentage;
pbProgess.Refresh();
lstStatus.Items.Add(" " + e.Step);
lstStatus.Refresh();
this.Refresh();
}
Application.DoEvents();
}
Run Code Online (Sandbox Code Playgroud)
这是"最先进的"吗?在我看来这有点乱??!
现有技术正在使用await.如果在这里不可能,至少将代码简化为单个Invoke调用.不需要在每个控件上调用,只需在UI线程上的任何位置调用.
该InvokeRequired检查不应该必需的,因为你应该知道什么的线程引发该事件.
在任何情况下,重复逻辑,如"Current state: " + e.Step真的是一个坏主意,我会在代码审查中失败,无论如何.
存在Application.DoEvents是一个非常糟糕的迹象.可能是一个误解,因为只在UI线程上调用它才有意义,但是为什么Invoke当它已经在UI线程上?!看起来像是一个矛盾.
lstStatus.Refresh();也是一种误解,可能是迷信.控制自动刷新(如果允许事件处理).