Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

debugging C# .NET after app closed

30 views
Skip to first unread message

Jeroen

unread,
Jan 29, 2008, 11:06:06 AM1/29/08
to
Hi,

I'm still struggling with a hard-to-reproduce scenario in my app where
we get an InvalidOperationException when closing the application. The
reason I'm posting about this again is because I'd love to hear some
suggestions on the following.

I've confirmed that the exception occurs *after* my app has finally
closed. If I set a breakpoint at the final '}' of my main method, then
go to the disassembly, and step through until *past* the final
statement (in my case "000004ef ret", whatever that may mean), only
*then* I receive the InvalidOperationException, in a VStudio debugger
screen that doesn't point to any particular user code...

My question then is: how do I debug this kind of problem??

I started to look into this using WinDbg, but that's not very user
friendly IMHO.

PS. This problem is caused by the WebBrowser control: if I exclude all
those controls in my app for a sec I won't get the exception. See also
my post here:
http://groups.google.nl/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/e9c40ec186b2cb93/8d8051941dd4e2c4?lnk=gst&q=InvalidOperationException+jeroen#8d8051941dd4e2c4

Any tips on how to debug this are very welcome.

Regards,
Jeroen

Ignacio Machin ( .NET/ C# MVP )

unread,
Jan 29, 2008, 11:21:06 AM1/29/08
to
Hi,


Do you know at least where you are getting the error at?
Use Application.ThreadException and AppDomain.UnHandleException and dump it
in a file (remember to check Exception.InnerException)

--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
"Jeroen" <merc...@gmail.com> wrote in message
news:8f04f677-0130-4c94...@n22g2000prh.googlegroups.com...

Jeroen

unread,
Jan 29, 2008, 11:33:05 AM1/29/08
to
> Do you know at least where you are getting the error at?

I wish, it just gives me a generic exception popup. I'm not sure how I
should _use_ 'ThreadException' or 'UnHandleException', could you
elaborate on that a bit?

Here's what I get from the exception screen:

/***********************************************/
/****** 'Copy exception to clipboard' ******/
System.InvalidOperationException was unhandled
Message="Invoke or BeginInvoke cannot be called on a control until
the window handle has been created."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller,
Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.BeginInvoke(Delegate method,
Object[] args)
at
System.Windows.Forms.WindowsFormsSynchronizationContext.Post(SendOrPostCallback
d, Object state)
at System.Windows.Forms.AxHost.ConnectionPointCookie.Finalize()

/***********************************************/

/***********************************************/
/*************** 'View detail' ****************/
// InnerException = null
// The rest seems to me just generic information
// on what the 'exception' type is.

Jeroen

unread,
Jan 29, 2008, 11:34:51 AM1/29/08
to
PS. The problem is more easily reproduced if I start the executable
directly (either in bin/debug or bin/release) than when running from
VStudio. In case of the latter I need to 'touch' much more of the
application to get the error after closing.

Willy Denoyette [MVP]

unread,
Jan 29, 2008, 12:28:38 PM1/29/08
to
"Jeroen" <merc...@gmail.com> wrote in message
news:3247d18b-0a95-49d0...@e10g2000prf.googlegroups.com...


What version of the Framework are you running this on?
Are you accessing the WebBrowser control from other threads than the Main
UI thread?
Also, did you host the WB control on a Form that runs on the Main UI thread?
I'm asking this because "someone" is trying to access the Control, from a
thread other than the main UI thread, after the Form has been destroyed and
it's handle invalidated.
I'm supposing this is the finalizer thread which should be OK, but I want to
be sure.

Willy.

Jeroen

unread,
Jan 30, 2008, 3:44:54 AM1/30/08
to
Hi,

(Different timezones I think, sorry for the delayed reply.)

> What version of the Framework are you running this on?

.NET 2 / studio 2005. The app was built originally in .NET 1.1 /
studio 2003, we upgraded to .NET 2 a while ago.


> Are you accessing the WebBrowser control from other threads than the Main
> UI thread?

No, not that I know of (any convenient way to check if I'm wrong?).


> Also, did you host the WB control on a Form that runs on the Main UI thread?
> I'm asking this because "someone" is trying to access the Control, from a
> thread other than the main UI thread, after the Form has been destroyed and
> it's handle invalidated.
> I'm supposing this is the finalizer thread which should be OK, but I want to
> be sure.

Yes, the form is created on the main UI thread - or at least I think
so. It is indirectly activated through the System.Activator namespace,
which might cause problems?


Thanks again for all the help and responses (this one's beginning to
drive me insane...).

By the way, next to solving the problem (of course prio #1) I'm also
still curious if there's a convenient way to debug this exception,
i.e. see what actually triggers it.

Regards,
Jeroen

Willy Denoyette [MVP]

unread,
Jan 30, 2008, 5:03:04 AM1/30/08
to
"Jeroen" <merc...@gmail.com> wrote in message
news:cf9c4fba-dfaa-4230...@l32g2000hse.googlegroups.com...

> Hi,
>
> (Different timezones I think, sorry for the delayed reply.)
>
>> What version of the Framework are you running this on?
>
> .NET 2 / studio 2005. The app was built originally in .NET 1.1 /
> studio 2003, we upgraded to .NET 2 a while ago.
>
>
>> Are you accessing the WebBrowser control from other threads than the Main
>> UI thread?
>
> No, not that I know of (any convenient way to check if I'm wrong?).
>
>
>> Also, did you host the WB control on a Form that runs on the Main UI
>> thread?
>> I'm asking this because "someone" is trying to access the Control, from a
>> thread other than the main UI thread, after the Form has been destroyed
>> and
>> it's handle invalidated.
>> I'm supposing this is the finalizer thread which should be OK, but I want
>> to
>> be sure.
>
> Yes, the form is created on the main UI thread - or at least I think
> so. It is indirectly activated through the System.Activator namespace,
> which might cause problems?
>

Does it mean that you are creating the WB control using System.Activator?
Question is why?
Are you using the WB control from the Tools box?

>
> Thanks again for all the help and responses (this one's beginning to
> drive me insane...).
>
> By the way, next to solving the problem (of course prio #1) I'm also
> still curious if there's a convenient way to debug this exception,
> i.e. see what actually triggers it.
>

Like I've said before, I'm pretty sure that this issue is related to the
finalizer who tries to clean-up the WB COM instance at CLR shutdown time.
For this, the finalizer thread needs to marshal the call from the finalizer
thread to the UI thread, but finds the Form destroyed and it's handle set to
null, bummer.

From this point on, the CLR does not allow any managed code to run in the
process, so, it's nearly impossible to debug this from within VS, you'll
have to use a native only debugger like Windbg.

Willy.


Jeroen

unread,
Jan 30, 2008, 5:30:50 AM1/30/08
to
> > (Different timezones I think, sorry for the delayed reply.)

Guess not :D?

>> Yes, the form is created on the main UI thread - or at least I think
>> so. It is indirectly activated through the System.Activator namespace,
>> which might cause problems?
>
> Does it mean that you are creating the WB control using System.Activator?
> Question is why?
> Are you using the WB control from the Tools box?

Yes. It's docked to fill on my own user control. Long story short, my
app chooses user controls at runtime (based on user input), that's why
we use System.Activator.


>> [...]


> Like I've said before, I'm pretty sure that this issue is related to the
> finalizer who tries to clean-up the WB COM instance at CLR shutdown time.
> For this, the finalizer thread needs to marshal the call from the finalizer
> thread to the UI thread, but finds the Form destroyed and it's handle set to
> null, bummer.

Ok, yes, I'm grasping this now. I guess my best option is then to
manually dispose all leftover WB controls when my application shuts
down, so the CLR doesn't have to anymore.


> From this point on, the CLR does not allow any managed code to run in the
> process, so, it's nearly impossible to debug this from within VS, you'll
> have to use a native only debugger like Windbg.

Okay, thanks. I was a bit afraid it would come to that, given that
concerning usability comparing Windbg to VStudio is like comparing
TurboC-1.0 to C# 2 :D.


Thanks for all the insights and tips Willy.

If I find a solution to this I will post it...

-Jeroen

Willy Denoyette [MVP]

unread,
Jan 30, 2008, 6:29:33 AM1/30/08
to
"Jeroen" <merc...@gmail.com> wrote in message
news:6f55d436-e14e-49fd...@e4g2000hsg.googlegroups.com...

>> > (Different timezones I think, sorry for the delayed reply.)
>
> Guess not :D?
>
>
>
>>> Yes, the form is created on the main UI thread - or at least I think
>>> so. It is indirectly activated through the System.Activator namespace,
>>> which might cause problems?
>>
>> Does it mean that you are creating the WB control using System.Activator?
>> Question is why?
>> Are you using the WB control from the Tools box?
>
> Yes. It's docked to fill on my own user control. Long story short, my
> app chooses user controls at runtime (based on user input), that's why
> we use System.Activator.
>

I see, I guess you can't produce a small repro?

>
>>> [...]
>> Like I've said before, I'm pretty sure that this issue is related to the
>> finalizer who tries to clean-up the WB COM instance at CLR shutdown time.
>> For this, the finalizer thread needs to marshal the call from the
>> finalizer
>> thread to the UI thread, but finds the Form destroyed and it's handle set
>> to
>> null, bummer.
>
> Ok, yes, I'm grasping this now. I guess my best option is then to
> manually dispose all leftover WB controls when my application shuts
> down, so the CLR doesn't have to anymore.
>

Well, there is a lot of clean-up you can do in your Form "OnClosing" event
handler, especially you should dispose of the WB control, so that the
finalizer doesn't have to do at process shutdown time.

>
>> From this point on, the CLR does not allow any managed code to run in the
>> process, so, it's nearly impossible to debug this from within VS, you'll
>> have to use a native only debugger like Windbg.
>
> Okay, thanks. I was a bit afraid it would come to that, given that
> concerning usability comparing Windbg to VStudio is like comparing
> TurboC-1.0 to C# 2 :D.
>

Well all depends what you are used to, I'm using Windbg since years and find
it difficult to use the VS debugger, pretty interface that's true, but
sometimes I'm asking "where's the meat?" to finally find out that it's not
there ;-).

>
> Thanks for all the insights and tips Willy.
>
> If I find a solution to this I will post it...

Good luck.

Willy.


Jeroen

unread,
Feb 4, 2008, 7:56:22 AM2/4/08
to
Sorry to bump an old thread, but it seems I have fixed my notorious
problem. After what I went through :) I want to help out anyone who
searches the web with the same problem ends up in this particular
thread. Here goes:

I added a class WebBrowserTracker with two methods:

AddInstantiatedBrowser(browser)
DisposeInstantiatedBrowserControls()

In each UserControl or other class where I have a webbrowser
instantiated I call the first method, which keeps track of all
webbrowser controls. At the end of my Main method I call the latter
method, which looks like this:

public static void DisposeInstantiatedBrowserControls()
{
foreach (System.Windows.Forms.WebBrowser control in
instantiatedBrowserObjects)
if (control != null &&
control.Disposing != true)
control.Dispose();
}

It ain't pretty, and I still don't fully understand why/how the some
WebBrowser controls do stuff after my app closes, but hey: this fixed
my problem (or so it seems, time will tell more).

Regards,
Jeroen

Jeroen

unread,
Feb 4, 2008, 7:57:10 AM2/4/08
to
PS. Willy, thanks for your explanations and tips, that led me to
solving this!

-Jeroen

Willy Denoyette [MVP]

unread,
Feb 5, 2008, 6:42:32 AM2/5/08
to
"Jeroen" <merc...@gmail.com> wrote in message
news:9ee526c2-696d-4c65...@v67g2000hse.googlegroups.com...


Well, it's not the browser control who does stuff after your application
closes, it's the finalizer thread that calls the finalize method on the WB
control wrapper (the RCW) after the form is closed. This is one of the
managed process shutdown actions performed by the CLR, this is yet another
reason to dispose of the WB control when you are done with it, instead of
relying on the finalizer to do the right thing.

Willy.

Jeroen

unread,
Feb 5, 2008, 8:22:12 AM2/5/08
to
Willy, thanks again for the explanation. I wasn't aware of the fact
there are types of objects I need to dispose of myself: I was under
the impression that for all managed code (also if it's only a wrapper
for unmanaged code) I needn't worry about it.

To pose one last question then, I would like to know if there's a list
of controls other than the WebBrowser that need this type of
treatment?

Thanks.

-Jeroen

0 new messages