代码之家  ›  专栏  ›  技术社区  ›  Bill

阻止开发人员调用System.Windows.Forms.Application.DoEvents()的最佳方法是什么?

  •  3
  • Bill  · 技术社区  · 16 年前

    这并不是在设计评审、代码评审中发现的。该守则于两年前与第一个版本一起插入;该应用程序总是“不稳定”,但最近的更改在更大程度上暴露了再进入问题。

    此事件是Application.DoEvents在我们的组织中第二次导致失败和多工时调试。在本例中,通过简单地注意到隐藏在异步任务的复杂事件处理程序中的调用就发现了它。

    您建议如何防止此问题再次发生:

    • 开发人员培训?
    • 代码分析规则(为什么这还不是一个内置规则?)

    8 回复  |  直到 16 年前
        1
  •  8
  •   Daniel Earwicker    16 年前

    每次集中构建应用程序时,请在每个程序集上运行:

    ildasm MyAssembly.exe /TEXT
    

    System.Windows.Forms.Application::DoEvents
    

        2
  •  4
  •   Shoban    16 年前

        3
  •  3
  •   Community Mohan Dere    8 年前

    所有这些。在你期待任何成功的机会之前,你需要先教给人们规则。你可能还想告诉人们,为什么规则很重要。

    Do you have coding standards? If so, how are they enforced?

        4
  •  3
  •   JaredPar    16 年前

    防止这种情况发生的一种更有效的方法是编写一个FxCop规则来标记此API的用法。如果FxCop作为构建过程的一部分被启用,这将尽早消除它,构建

        5
  •  1
  •   Ed Swangren    16 年前

    我建议进行一些异步编程(使用BeginInvoke)方面的培训,并在另一个线程的后台执行耗时的任务。

        6
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    16 年前

    除了试图阻止电话被使用,还有 (以及其他问题):

    在代码中使用大量断言。

    MSQuant 使用DoEvents()和重新进入。但它很早就被人发现了

    断言很早就发现了错误,我保存了很多, 许多小时的调试时间。此外,它们可能会捕捉到这样的虫子 否则会被忽略(例如产生不正确的结果)。

    这是一种非常有效的做法(高回报与努力比)。 很多年前我就知道了,从那以后我一直在使用它。 当然,它并不能取代其他做法:声音 软件工程、单元测试、代码标准、,

    用户停止工作)或中止程序。可能是 配置为将信息发送到日志系统(例如。

        7
  •  -1
  •   dbasnett    16 年前

    “我们刚刚花了300个工时在现场修复了一个有缺陷的应用程序。这一切都归结为调用application.DoEvents(重入问题)。”

    首先,我要说的是,我并不提倡将Application.DoEvents用于临时用途,而是在long=0的情况下编写一个for x到long.maxvalue循环,看看UI的响应性如何。

    Private Sub foo()
        stpw.Reset() : stpw.Start()
        Do
        Loop While stpw.ElapsedMilliseconds < 1000
        stpw.Stop()
        Debug.WriteLine("foo")
    End Sub
    Dim stpw As New Stopwatch
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Debug.WriteLine("")
        Debug.WriteLine("but click")
        Dim t As New Threading.Thread(AddressOf foo)
        t.Start()
        Do
            Threading.Thread.Sleep(10)
            'Application.DoEvents() 'uncomment to change the behavior
        Loop While stpw.IsRunning
        Debug.WriteLine("but exit")
    End Sub
    

        8
  •  -1
  •   dbasnett    16 年前

    没有DoEvents会使这段代码变得“好”吗?

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        'simulate a long running task
        For x As Long = 1 To Long.MaxValue - 1
            'the absence of Application.DoEvents() is poor design IMHO
        Next
    End Sub