2011-09-18 32 views
6

我有一個ac#(.net 4.0)winforms應用程序,它幾乎每週8個小時在XP SP 3上運行。它大多數時間工作正常,有時幾個月。然後,它似乎陷入了一個不好的咒語,並且每天一次,連續幾天,在不同的時間出現訪問衝突異常。我試着查看轉儲文件,並捕獲訪問衝突異常來查看堆棧;無論哪種方式,我得到幾乎相同的堆棧:訪問衝突:試圖讀取或寫入受保護的內存

Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at System.Windows.Forms.NativeWindow.DefWndProc(Message& m) 
    at System.Windows.Forms.ToolTip.WndProc(Message& msg) 
    at System.Windows.Forms.ToolTip.ToolTipNativeWindow.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(Form mainForm) 

我有一個非常艱難的時間來修復這一點,因爲堆棧跟蹤不是非常有用。首先,我甚至不確定我是否可以信任堆棧跟蹤:程序是否到達那裏(看起來它試圖顯示一些工具提示,這當然是可能的),因爲內存已經損壞,或者如果程序真的應該合法那裏,但一些數據內存已損壞。其次,假設堆棧跟蹤是正確和可信的,我沒有看到一種方法來找出什麼是破壞內存...我們沒有做任何事情一致觸發訪問衝突...應用程序日誌不顯示任何其他捕獲異常之前...事件日誌不會顯示任何條目與訪問衝突同時...任何提示如何進一步診斷此?

更新2011-10-11:我已經在捕獲異常,但圍繞Application.Run()方法。在這一點上,似乎現在做太多太遲了。爲了防止由於硬件/驅動程序錯誤而導致發生此異常,並且未指出應用程序的內存已損壞 - 是否還有其他地方可以捕獲異常(並顯示它,但讓應用程序繼續運行)?

更新2012-03-04:我再次得到異常,這次顯示一個相當小的表單(只包含一個文本框和一個ok按鈕)。我正在使用TextBox.AppendText()。我只是碰巧在同一時間瀏覽這個comment。 AppendText()會導致問題嗎?當發生「原始」訪問衝突時,他們往往會在顯示一個包含richtextbox的表單之後發生,我也在這個表單上調用AppendText()。情節變濃了!

更新2012-03-06:我刪除了AppendText,只是使用TextBox.Text =代替,但今天我再次遇到了訪問衝突異常。因此,AppendText似乎不是罪魁禍首。此外,在運行Windows 7的開發盒上發生了一次異常。因此,Windows XP或其他計算機(如內存問題)似乎沒有特殊情況。

+1

你在應用程序中執行任何PInvoke嗎?如果是的話,可能值得評論一下代碼(如果可能的話),看看它是否有區別。也可以看看這個http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/6adca20b-649f-41a4-8fa1-09534882d76c/,特別是來自「James Kovac」和「DejanR」的答案。 。可能與調試優化有關。 – Raghu

回答

5

我能發出感謝複製到this post。因此,一個解決方法似乎使用DataGridView.ShowCellToolTips = false禁用所有datagridview中的所有工具提示;但是,這並不理想。 A better work-around是調用

Application.EnableVisualStyles(); 

before any controls are created in the app

我確認無論DataGridView是否顯示自定義工具提示(使用CellToolTipTextNeeded)或不是。

0

不知道這是否會有所幫助,但這個問題似乎在.Net的舊版本中很常見,而且微軟甚至爲此發佈了一些修復程序。

一個初始修復情況如下,

http://support.microsoft.com/kb/923028

這裏是另一個。 http://support.microsoft.com/kb/975954

+0

謝謝。對於修補程序923028,我收到一條錯誤消息:「由於要升級的程序可能會丟失,或者升級修補程序可能會更新程序的不同版本,升級修補程序無法通過Windows Installer服務進行安裝。請確保程序在您的計算機上存在升級,並且您擁有正確的升級補丁。「 975954已成功安裝。讓我們看看它是否有效! – Jimmy

+0

今天早上有另一個訪問違規 - 因此,確認修復程序975954沒有解決問題:( – Jimmy

0

這是不容易的跟蹤/修復,因爲所有的信息是相當「通用」,所以這些都是一些普通的指針:

  • 是否總是在同一臺機器上發生的呢?
    如果是的話,那麼它可能是值得檢查機器(內存測試等,從引導Linux光盤或類似的運行)和/或在不同的機器上運行它,看它是否改變了......

  • 顯示工具提示時似乎發生異常......可能表明顯卡驅動程序出現問題...選擇不同的驅動程序和/或不同的屏幕分辨率等,看看會發生什麼

  • 您是否使用了一些第三方庫?
    如果所以可能值得檢查它們是否存在非託管內存問題(例如,使用內存分析器...)。檢查供應商是否有更新的版本等
    我前一段時間類似的事情,它竟然是一些第三方庫內部的非託管內存泄漏(通過內存分析器診斷)...我檢查供應商,並獲得其運行平穩,自從一個固定的版本...

+0

上週更新了驅動程序。我們有一個堅實的一週沒有崩潰,然後砰!今天下午崩潰:( – Jimmy

+0

作爲一個絕對不得已的事情:有時它有助於重新啓動每24小時左右... – Yahia

+0

是的,軟件本身每天關機,並且每週重新啓動計算機......似乎沒有幫助(即,崩潰可能發生在週一,之後重新啓動週末) – Jimmy

2

我們最近在做TextBox.AppendText()時也得到了AccessViolationException。試圖重現問題後,我們意識到TextBox不是問題。在我們的例子中,它是拖放功能。

下面是一個最小的項目(一個文本框形式),將再現異常:

using System; 
using System.Windows.Forms; 

namespace TestTextBoxAccessViolation { 
    public partial class Form1 : Form { 


     public Form1() { 
      InitializeComponent(); 
     } 

     private void Form1_DragEnter(object sender, DragEventArgs e) { 
      e.Effect = DragDropEffects.Copy; 
     } 

     private void Form1_DragDrop(object sender, DragEventArgs e) { 
      e.Data.GetData("DragImageBits"); 
      Form1 f = new Form1(); 
      f.textBox1.Text = "Keep resizing this window and you'll get an AccessViolationException after a while"; 
      f.Show(); 
     } 
    } 
} 

結論:不要使用「DragImageBits」。

0

我遭受了與OP相同的行爲。我修改了一個軟件並添加了兩個PInvoke方法(以改進UI)。不幸的是,我開始收到與OP相同的消息。在查看答案時,我找到了Raja Hindustani's。在註釋掉兩個PInvoke方法後,問題似乎消失了。

1

我發現這個問題不僅在WPF中發生(崩潰),而且在WinForms中。我的問題與OpenFileDialog有關。 這是很難說什麼是問題的根源,但仍然看來,與OpenFileDialog相關的Microsoft DLL有錯誤(對我來說,它是ComDlg32.dll)

我可以調用ShowDialog()函數的唯一方法是要在事件中打包並呼叫

this.BeginInvoke(
     new Action<YourObject, EventArgs>(YourObject_FileDialogOpened), new object[] 
                 { YourObjectInstance, e }); 

其中「this」是一個Control(例如,Form)。

BeginInvoke(...)您撥打的撥款將以正確的方式處理。

如果您在按鈕單擊事件或任何其他類似場景下使用OpenFileDialog調用,問題將不會出現。

相關問題