c# - 找出从后台线程访问了哪些 winforms 控件

标签 c# winforms devexpress

我们已经构建了一个巨大的 winforms 项目,已经进行了多年。

有时,我们的用户会遇到类似 this one 的异常.

这个问题的解决办法好像是:

don't acces UI components from a background thread

.

但是由于我们的项目是一个非常大的项目,有很多不同的线程,我们没有成功找到所有这些。

有没有办法检查(使用某些工具或调试选项)哪些组件是从后台线程调用的?

澄清:

我用一个 Form 创建了一个示例 winforms 项目,其中包含两个 Button

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Text = "Clicked!";
    }

    private void button2_Click(object sender, EventArgs e)
    {

        Task.Run(() =>
        {
            button2.BackColor = Color.Red; //this does not throw an exception
            //button2.Text = "Clicked"; //this throws an exception when uncommented
        });
    }
}

单击按钮时,button2 的背景色设置为红色。这发生在后台线程中(这被认为是不良行为)。但是,它不会(立即)抛出异常。我想要一种将此检测为“不良行为”的方法。最好是通过扫描我的代码,但如果只能通过调试来实现(因此一旦从后台线程访问 UI 组件就暂停)也可以。

最佳答案

我有 2 个建议一起使用,第一个是名为 DebugSingleThread 的 Visual Studio 插件.

您可以卡住所有线程并一次处理一个线程(显然是非主 UI 线程)并查看每个线程对控件的访问。我知道这很乏味,但使用第二种方法还不错


第二种方法是获取重现问题的步骤。如果您知道重现它的步骤,就会更容易看出是什么原因造成的。为此,我做了这个 User Action Log Github 上的项目。

它会记录用户的每一个 Action ,你可以在这里阅读:User Activity Logging, Telemetry (and Variables in Global Exception Handlers) .

我建议您还记录线程 ID,然后当您能够重现问题时,转到日志末尾并计算出确切的步骤。它并不像看起来那么痛苦,而且非常适合获取应用程序遥测数据。

您可以自定义此项目,例如捕获一个 DataSource_Completed 事件或添加一个虚拟 DataSource 属性来设置真正的 Grids DataSource 属性并引发一个 INotifyPropertyChanged 事件 - 如果它是一个非主要的然后是线程 ID Debugger.Break();


我的直觉是你正在后台线程中更改控件(例如网格)的数据源(为了那种非卡住的感觉),这会导致同步问题。这就是发生在其他经历过这种情况的 DevExpress 客户身上的情况。其讨论here在与您引用的线程不同的线程中。

关于c# - 找出从后台线程访问了哪些 winforms 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48113854/

相关文章:

c# - 文件未完全下载

delphi - 过滤 TcxTreeList

jquery - 使用jquery ajax调用导出到excel

c# - 如何在 onrowcommand 上调用 javascript 函数?

c# - 用于单元测试的虚拟 ObjectList 生成器

c# - 在 WinForms 中绘制垂直堆叠的文本

c# - Windows 窗体上的 log4net 不写入日志文件

vb.net - 限制您可以在 Windows 窗体文本框中输入的字符数

entity-framework - 手动 DAL & BLL 与 ORM

c# - 在 C# 中从队列中出列字节的最有效方法