2016-01-30 131 views
2

我寫的Winforms.net 4應用程序的客戶現在經常報告由於'參數無效'錯誤導致的崩潰。參數是無效的異常和ResourceManager

所有的「圖像」小實際上資源的圖標(16×16像素),並沒有那麼多。他們都與資源管理器檢索,和幾乎所有的人都通過設計器生成的代碼

ResourceManager中似乎每當我用它來讀取圖標資源來實例化一個新的位圖被分配給按鈕。所以這些都沒有明確地處理。

我試着看看GDI對象的數量和用戶句柄的數量。句柄的數量是穩定的,並且GDI對象的數量似乎緩慢增加:在應用程序中打開/關閉(並處置)模態表單之後,還有更多的使用。

  • 由於GDI對象的數量變高,參數無效嗎?
  • 如果是,是否由ResourceManager引起?
  • 我是否必須顯式釋放由資源管理器創建的資源?
  • 如果否,那麼參數無效來自哪裏?

在這裏,當我改變上的toolstripmenuitem

System.ArgumentException: Parameter is not valid. 
    at System.Drawing.Image.get_RawFormat() 
    at System.Windows.Forms.ToolStripItem.set_Image(Image value) 

通訊碼所顯示的圖標:

​​

這與用於顯示圖標的圖片框

System.ArgumentException: Parameter is not valid. 
    at System.Drawing.Image.get_FrameDimensionsList() 
    at System.Drawing.ImageAnimator.CanAnimate(Image image) 
    at System.Drawing.ImageAnimator.ImageInfo..ctor(Image image) 
    at System.Drawing.ImageAnimator.Animate(Image image, EventHandler onFrameChangedHandler) 
    at System.Windows.Forms.PictureBox.Animate(Boolean animate) 
    at System.Windows.Forms.PictureBox.Animate() 
    at System.Windows.Forms.PictureBox.OnParentChanged(EventArgs e) 
    at System.Windows.Forms.Control.AssignParent(Control value) 
    at System.Windows.Forms.Control.ControlCollection.Add(Control value) 

對應的代碼:

this.pcbIcon.Image = global::MyProject.Properties.Resources.information; 

由於

EDIT 19/02

記得我添加了片的下面的代碼注意到在參數的增加之前(從 http://www.codeproject.com/Tips/513764/Repainting-WinForms-windows-safely-inside-a-proces採取)是無效的問題。我不知道這是相關

public static class WinFormUtils 
{ 
    /// <summary> Processes all Paint events only </summary> 
    public static void DoPaintEvents() 
    { 
     //MessageFilter registration 
     Application.AddMessageFilter(PaintMessageFilter.Instance); 
     //Process messages in the queue 
     Application.DoEvents(); 
     //MessageFilter desregistration 
     Application.RemoveMessageFilter(PaintMessageFilter.Instance); 
    } 

    /// <summary> Custom message filter </summary> 
    private class PaintMessageFilter : IMessageFilter 
    { 
     static public IMessageFilter Instance = new PaintMessageFilter(); 

     #region IMessageFilter Members 

     /// <summary> Message filter function </summary> 
     public bool PreFilterMessage(ref System.Windows.Forms.Message m) 
     { 
       return (m.Msg != 0x000F); //WM_PAINT -> we only let WM_PAINT messages through 
     } 

     #endregion 
    } 
} 

編輯27/10/2016:該參數無效確實是由一段代碼上面造成的。所以,如果你不知道你在做什麼,就不要搞砸Windows消息!

回答

0

由於GDI對象的數量過高,該參數無效嗎?

是的,這是很可能的。例外的質量很差,GDI +不會生成好的錯誤代碼。 「參數無效」並不僅僅意味着「它沒有工作」。由於具有太多GDI對象或桌面堆空間不足是主要的「它沒有工作」的原因。

如果是,則它引起的ResourceManager?

不完全是。當您獲取圖像資源時,您將成爲該對象的所有者。調用它的Dispose()方法是你的工作。這很少完成,實際上不會造成麻煩。除非您創建的程序永遠不會對GC堆施加足夠的壓力。這種程序使用大量的控件和圖形,但不管理大量數據。如果沒有足夠的第二代集合,那麼這些對象的終結器將不會運行,並且本機操作系統對象不會被破壞。

是否必須顯式釋放由資源管理器創建的資源?

是。

GDI在任務管理器中的對象計數器是一個讓你誠實的。別忘了還要看看另一個經典麻煩製造者USER Objects。定期調用GC.Collect()是GDI對象計數的快速修復。如果你不使用足夠的GC堆,這不是不合理的。總是從內存分析器獲得第二個意見,它最清楚,我們只是在我們看不到報告時才猜測它。

+0

謝謝您的回覆。你會知道我添加的這段代碼(編輯19/02)是否可以負責?這很難測試,因爲我的機器上沒有問題。 – David

相關問題