2012-01-31 58 views
1

我有一個非常簡單的形式,裏面有圖像(「加載」GIF)。就這樣。有時,當我的程序真的忙於做某些事情時,我想要顯示此表單以告訴用戶系統正忙,並且我在單獨的線程上這樣做,(MainThreadBase.SystemBusy是表單它是靜態的):在GDI +中出現的一般性錯誤(不在ASP.NET中)

public static void SetSystemBusy(bool isBusy) 
{ 
    try 
    { 
     if (isBusy) 
     { 
      if (threadSystemBusy == null) 
      { 
       if (MainThreadBase.SystemBusy == null) 
       { 
        MainThreadBase.SystemBusy = new Controls.OutputControls.OutputControl_SystemBusy(); 
       } 
       threadSystemBusy = new Thread(() => SetSystemBusyThread()); 
       threadSystemBusy.Start(); 
      } 
     } 
     else 
     { 
      if (threadSystemBusy != null) 
      { 
       threadSystemBusy.Abort(); 
       threadSystemBusy.Join(); 
       threadSystemBusy = null; 
      } 
      MainThreadBase.SystemBusy = null; 
     } 
    } 
    catch (Exception e) 
    { 
     LogFile.appendLine_error(e); 
    } 
} 

private static void SetSystemBusyThread() 
{ 
    try 
    { 
     MainThreadBase.SystemBusy.BringToFront(); 
     MainThreadBase.SystemBusy.TopLevel = true; 
     MainThreadBase.SystemBusy.TopMost = true; 
     MainThreadBase.SystemBusy.ShowDialog(); 
    } 
    catch (ThreadAbortException tae) 
    { 
    } 
    catch (Exception e) 
    { 
     LogFile.appendLine_error(e); 
    } 
} 

所以,有時(我不能看到一個模式,但我懷疑這是當我嘗試以顯示它不止一次在同一時間,但你可以看到我確信有隻是一個活動線程)它拋出這個錯誤,我不知道爲什麼或它在哪裏拋出。堆棧跟蹤如下:

at System.Drawing.Image.SelectActiveFrame(FrameDimension dimension, Int32 frameIndex) 
    at System.Drawing.ImageAnimator.ImageInfo.UpdateFrame() 
    at System.Drawing.ImageAnimator.UpdateFrames() 
    at System.Windows.Forms.Label.OnPaint(PaintEventArgs e) 
    at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) 
    at System.Windows.Forms.Control.WmPaint(Message& m) 
    at System.Windows.Forms.Control.WndProc(Message& m) 
    at System.Windows.Forms.Label.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(Int32 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 PCC.Program.Main() in C:\Documents and Settings\rhervas\My Documents\Proyectos\PCC\SCFMV_MAIN\Program.cs:line 46 

46號線在Program.cs僅僅是這樣的:

Interface_Login interfaceLogin = new Interface_Login(); 
Application.Run(interfaceLogin); 

所以它告訴我什麼。我該如何解決這個問題? (注意:我已經看到很多與這個錯誤有關的問題,並沒有一個適合我的情況,我已經看到它們中的很多都是使用MemoryStream解決的,但是我沒有編輯或保存任何圖像。在這裏,我去。)

+0

爲什麼「不是ASP.NET」的評論? – 2012-01-31 10:28:26

+2

不好意思說,但你做的一切都是錯誤的。你應該在另一個線程上執行繁重的工作,而不是ShowDialog()。 – 2012-01-31 10:31:36

+0

「不是ASP.NET」是因爲我在StackOverflow中看到過這個問題,其中很多都與asp.net和權限問題有關,事實並非如此。我知道我應該在另一個線程上做繁重的工作,但是它是由「第三方公司」庫完成的,我不能修改它(相信我,我試圖在另一個線程上做,而圖書館不允許這樣做) 。順便說一句,我想另一種方法,它正在工作,所以我沒有這個錯誤了...... – DarthRoman 2012-01-31 11:57:43

回答

2
if (MainThreadBase.SystemBusy == null) 
{ 
    MainThreadBase.SystemBusy = new Controls.OutputControls.OutputControl_SystemBusy(); 
} 

這是你調用threadSystemBusy.Abort()後麻煩的沃土。中止線程上使用的對象狀態非常不可預知。對他們唯一合理的處理方式就是處置它們,像你一樣重新使用它們就是在尋求麻煩。

但是這只是從根本上弄錯了。緩慢的操作必須在工作者線程上執行,而不是UI線程。通過COM STA合同阻止UI線程禁止。 BackgroundWorker類可以幫助您正確使用。啓動它後只需顯示對話框,在RunWorkerCompleted事件中關閉對話框。再加上你想要對操作結果進行的任何操作,比如綁定或更新控件。將慢代碼移到DoWork事件處理程序中。

+1

我知道,但是如果你使用單例對象,即使使用互斥體,這個第三方庫也不能很好地工作,並且我使用單例對象。所以,至少從我知道的,我不能使用線程(我試過並得到一些錯誤)。但是當我有更多時間時,它就在我的列表上:找出如何使用線程來完成它。無論如何,謝謝你的支持者! – DarthRoman 2012-01-31 16:52:26

相關問題