簡體   English   中英

阻止開發人員調用System.Windows.Forms.Application.DoEvents()的最佳方法是什么?

[英]What is the best way to stop developers from calling System.Windows.Forms.Application.DoEvents()?

我們花了300個工時來修復現場的錯誤應用程序。 這一切都歸結為調用Application.DoEvents(re-entrancy problem)。

這沒有在設計評論,代碼評論中發現。 兩年前插入的代碼是第一個版本; 應用程序總是“不穩定”,但最近的變化在很大程度上暴露了重新入侵問題。

此事件是我們組織中第二次發生Application.DoEvents導致失敗和多人工作時間的調試。 在這種情況下,通過簡單地注意到調用,在一個異步任務的復雜事件處理程序中埋下來,就發現了它。

你有什么建議可以防止這個問題再次發生:

  • 添加簽入門到源代碼管理?
  • 開發者培訓?
  • 代碼分析規則(為什么這不是內置規則?)

如何執行編碼練習?

每次集中構建應用程序時,在每個程序集上運行它:

ildasm MyAssembly.exe /TEXT

然后搜索輸出:

System.Windows.Forms.Application::DoEvents

如果找到,請將構建標記為失敗,就好像它是編譯錯誤一樣。

維護開發標准並將其添加到其中。

上述所有的。 在你預期任何成功的機會之前,你需要教會人們規則。 您可能還想告訴別人,為什么規則很重要。

遵循那些阻止你違反規則的工具總是一個好主意。 您的具體問題可能是FxCop規則或登記政策的地址。

相關問題: 你有編碼標准嗎? 如果是這樣,他們是如何執行的?

防止這種情況的更有效方法是編寫一個標記此API用法的FxCop規則。 如果在構建過程中啟用了FxCop,那么這將在盡可能早的時候消除它

除了試圖阻止使用調用之外,有一種方法可以使它更容易發現這樣的問題(以及其他問題):

在代碼中使用大量ASSERT。

我的應用程序( MSQuant )中有類似的問題與DoEvents()和re-entrancy。 但是在我自己的測試過程中,它被ASSERT提前捕獲,從未影響任何用戶。

ASSERT早期發現錯誤,我節省了許多很多小時的調試時間。 此外,他們可能會捕獲否則會被忽視的錯誤(例如產生不正確的結果)。

這是一種非常有效的練習(高獎勵率)。 我很多年前就已經了解它,並且從那時起就開始使用它。 當然,它並不能取代其他做法:合理的軟件工程,單元測試,代碼標准,驗收測試,代碼檢查。

請注意,觸發ASSERT可能不一定會導致ASSERT對話框(停止正常執行或停止用戶工作)或中止程序。 它可以配置為通過網絡等將信息發送到日志系統(例如,文件)。

我建議對異步編程進行一些培訓(使用BeginInvoke),並在另一個線程的后台執行耗時的任務。

“我們只花了300個工時來修復現場的一個錯誤的應用程序。這一切都歸結為調用Application.DoEvents(re-entrancy problem)。”

首先讓我說我不是在提倡使用Application.DoEvents進行臨時使用,而是將x為long = 0寫入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

因此,假設我最初在沒有違規聲明的情況下編寫它,但是用戶抱怨UI沒有響應。 所以我然后添加DoEvents,但是當用戶雙擊按鈕時,我現在得到奇怪的結果。 是問題DoEvents還是只是糟糕的設計。 在這種情況下,我會投票給糟糕的設計。

缺少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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM