經過一些更多的測試後,我發現這個問題可能是由於圖像以某種方式未被及時加載而被克隆到位圖並顯示。這是可能的還是不可以的?System.Drawing - 參數無效
注意:是的,在標題中有這個錯誤的其他問題,但從一些研究來看,它似乎是一個模糊的錯誤,有很多可能的原因。我沒有發現任何與我的情況相同的問題。
我收到以下錯誤消息。
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
它來自此代碼。看似隨意(即,有時工作,有時它不會次數越多它的連續運行,無需重新啓動VS和重建項目,越有可能是失敗。):
private Bitmap GetSprite(bool anim, int tsIndex, int tileIdx) {
System.Drawing.Rectangle cloneRect;
string prefix = (anim) ? "A" : "S";
using (Bitmap b = new Bitmap(prefix + tsIndex.ToString() + ".png")) {
if (anim) {
cloneRect = new System.Drawing.Rectangle(BaseObjects.A_AnimSpriteSets[tsIndex].StaticRecs[tileIdx].X, BaseObjects.A_AnimSpriteSets[tsIndex].StaticRecs[tileIdx].Y, BaseObjects.A_AnimSpriteSets[tsIndex].RecWidth, BaseObjects.A_AnimSpriteSets[tsIndex].RecHeight);
} else {
cloneRect = new System.Drawing.Rectangle(BaseObjects.A_StaticSpriteSets[tsIndex].StaticRecs[tileIdx].X, BaseObjects.A_StaticSpriteSets[tsIndex].StaticRecs[tileIdx].Y, BaseObjects.A_StaticSpriteSets[tsIndex].RecWidth, BaseObjects.A_StaticSpriteSets[tsIndex].RecHeight);
}
return b.Clone(cloneRect, b.PixelFormat);
}
}
具體來說,第四行:
using (Bitmap b = new Bitmap(prefix + tsIndex.ToString() + ".png"))
代碼的簡化目的是返回包含基於一個spriteset索引和子畫面索引spriteset精靈的位圖。該位圖顯示在PictureBox中,直到它被更改爲不同的圖像。我知道邏輯起作用的事實;這不是問題。我用來測試的.png是384 * 256。
所有參數設置正確,所有引用的文件都在那裏,一切似乎都是按順序的。最奇怪的是,有時它起作用,有時它不起作用。這使我相信它可能是System.Drawing
本身的內存泄漏,但我似乎無法追蹤它。
編輯:更新的代碼並添加堆棧跟蹤。仍具有儘管設置所述位圖相同的問題,當它們不再使用(參見下面的代碼例如位圖是怎樣佈置)。
if (Sprite.Image != null) { Sprite.Image.Dispose(); }
Sprite.Image = GetSprite(true, tsIdx, tileIdx);
堆棧跟蹤:
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Bitmap..ctor(String filename)
at CreationTool.Main.GetSprite(Boolean anim, Int32 tsIndex, Int32 tileIdx) in F:\~\~\CreationTool\Main.cs:line 420
at CreationTool.Main.Input_EnemySprite_SelectedIndexChanged(Object sender, EventArgs e) in F:\~\~\CreationTool\Main.cs:line 107
at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)
at System.Windows.Forms.ComboBox.set_SelectedIndex(Int32 value)
at CreationTool.States.State_Enemy.populateForm() in F:\~\~\CreationTool\States\State_Enemy.cs:line 28
at CreationTool.States.State_Enemy.Load(String name) in F:\~\~\CreationTool\States\State_Enemy.cs:line 22
at CreationTool.Main.btnLoad_Click(Object sender, EventArgs e) in F:\~\~\CreationTool\Main.cs:line 174
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(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)
at CreationTool.Program.Main() in F:\~\~\CreationTool\Program.cs:line 15
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
你需要調用'Dispose'在'位圖B'你克隆後。位圖使用非託管資源,這可能會導致內存壓力問題。我會用一個使用語句來包裝它。 – pstrjds
謝謝,這似乎已修復它。改變成答案? – Djentleman
您應該在您的應用程序的'Main'中添加try/catch,並將異常轉儲到控制檯或將其記錄下來,以便您可以查看堆棧跟蹤並確切知道其來源。 – pstrjds