开发者

What is the origin of this set_Visible exception during shutdown of winforms application?

I have wrapped the Application.Run method in try/catch

[STAThread]
private static void Main(string[] args)
{
   try {
       MyClient client = new MyClient();
       client.Run(args);
    }
    catch (Exception ex) { log.Error("Failed to start client",ex); }
}

Where MyClient is just:

class MyClient : WindowsFormsApplicationBase

and during every shutdown I get this exception

System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'MainView'.
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.Form.CreateHandle()
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
   at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
   at System.Windows.Forms.Control.set_Visible(Boolean value)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
  at MyProgram.Main(String[] args) in C:\svn\trunk\MyProg开发者_C百科ram\client\MyProgram\Program.cs:line 54

If I set a breakpoint in the debugger in the catch block my callstack is all empty except for the client.Run(..).

As far as I can understand the stacktrace the problem is somewhere some code is doing MainView.Visible = .... but I can find anything in my code that resembles this.

How can I figure out the origin of the exception?

The MainView is created like this inside MyClient:

protected override void OnCreateMainForm()
{
   string[] args = Environment.GetCommandLineArgs();
   try {
        MainView mainView = new MainView(args);
        this.MainForm = mainView;
        Application.EnableVisualStyles();
        Application.Run(mainView);
   }catch(Exception ex){ log.Warn("Exception in OnCreateMainForm",ex); }
}

And closing like this:

public void OnKilled()
{
   log.Debug("OnKilled. Exiting");
   Application.Exit();
}

MainView is defined like:

public partial class MainView : Form
{
    private void InitializeComponent()
    {
        this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainView_FormClosing);
    }
    private void MainView_FormClosing(object sender, FormClosingEventArgs e)
    {
        log.DebugFormat("'MainView_FormClosing': {0}",e.CloseReason);
        if (e.CloseReason == CloseReason.WindowsShutDown || e.CloseReason == CloseReason.ApplicationExitCall)
        {
            e.Cancel = false;
            Application.Exit();
        }
}


Can you please post the code that you use in order to create the main window, and the code that you use in order to close it?

Without seeing more code, I would guess that somewhere in your code you are calling Dispose on the windows, instead of using Close. But that's just a guess.

By the way, why are you using WindowsFormsApplicationBase if this is a C# program?


Aha!

It turns out that Application.Run in OnCreateMainForm is the big No-No. WindowsFormsApplicationBase takes over the ApplicationRun when OnCreateMainForm returns so in my case I only returned from OnCreateMainForm when MainForm already were disposed hence the exception :(

 protected override void OnCreateMainForm()
 {
     string[] args = Environment.GetCommandLineArgs();
     try {
           MainView mainView = new MainView(args);
           this.MainForm = mainView;
           Application.EnableVisualStyles();
     }...
 }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜