线程安全事件-这是“线程安全事件”吗;“干净”;方法

本文关键字:线程 安全事件 干净 方法 这是 | 更新日期: 2023-09-27 18:25:34

我偶然发现了专业库中的一些代码,不确定这是否是处理跨线程事件调用的干净方法。

下面的代码在表单应用程序中。线程调用是从一个类中进行的,该类本身启动一个新线程并接收消息:

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();也是一种误解,可能是迷信。控制自动刷新(如果允许事件处理)。

使用invoke时,会在队列中添加一条语句,由UI线程处理。

使用这个简单的解决方案:

private void Library_StatusChanged(object sender, AbstractTestCase.StatusChangedEventArgs e)
{
    this.lblProgress.Invoke((MethodInvoker)delegate ()
    {
        lblProgress.Text = "Current state: " + e.Step;
    });
    this.pbProgess.Invoke((MethodInvoker)delegate ()
    {
        pbProgess.Value = e.Percentage;
    });
    this.lstStatus.Invoke((MethodInvoker)delegate ()
    {
        lstStatus.Items.Add("    " + e.Step);
    });
}