GDI+中出现了一个一般性错误(不在ASP.NET中)

本文关键字:错误 一般性 不在 NET ASP 一个 GDI+ | 更新日期: 2023-09-27 18:21:54

我有一个非常简单的表单,里面有一个图像(一个"加载"GIF)。仅此而已。有时,当我的程序真的忙于做某事时,我想显示这个表单来告诉用户系统正忙,我在一个单独的线程上这样做(MainThreadBase.SystemBusy是表单,它是静态的):

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

Program.cs中的第46行就是这样的:

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

所以它什么也没告诉我。如何解决此问题?

(注意:我看到了很多与此错误相关的问题,但没有一个符合我的情况。我看到其中许多问题都是使用MemoryStream解决的,但我没有编辑或保存任何图像。说了这些,我就开始了。)

GDI+中出现了一个一般性错误(不在ASP.NET中)

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

在调用threadSystemBusy.Abort()之后,这是麻烦的温床。在中止的线程上使用的对象的状态是非常不可预测的。对它们唯一合理的做法就是处理它们,像你一样重复使用它们就是自寻烦恼。

但这只是从根本上弄错了。慢速操作必须在工作线程上执行,而不是在UI线程上执行。COM STA合约禁止阻塞UI线程。BackgroundWorker类可以帮助您做好这件事。只需在启动对话框后显示对话框,然后在RunWorkerCompleted事件中关闭对话框。再加上您想对操作结果执行的任何其他操作,如绑定或更新控件。将慢速代码移到DoWork事件处理程序中。