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