COM stops working?? Please help

F

Fruber Malcome

I have a C# application that starts as a form.

This form has a member that holds an instance of a CustomClass that
automates word by creating new commandbards / hiding others and handling the
messages from them.

The instance of this object is created during the initialize even of the
form.

If I click exit on word, it closes this form (just a blank form for now)
If I click exit on the form (the x button) - it closes both the form and
word.

Once the initialize of the form is complete and word has started - all of my
commandbars, menubars all appear and messages are handled.
If after sometime goes by (opening dialogs / closing dialogs etc - something
that creates objects and let's them get disposed) - all of a sudden none of
my message handlers are working. - I get the macro not found or security
setting too high error message.

I put some thought into it and assumed it must have had something todo with
garbage collection, so I then call (for testing purposes):
GC.Collect()
GC.WaitForPendingFinalizers()
at the end of my initialize function (in the form)
Everything acted the same.
I then put this same exact two lines of code at the end of my constructor in
the AutomationClass, and now after initialization - it all stops working
immediately.

I still have all my commandbars etc, but the handlers immediatly stop
working.

I've checked the contructor - and functions that are called outside of the
constructor - I see no variables being called only within that scope that
would make any difference.

I've attached WinDebug to this application while running, I see nothing
going on that shouldn't. (no threads exiting or something like that - that
would lead me to isolate the problem).

I suspect it may have something to-do with the fact that because this
application performs all the setup for commandbars and menubars, and then
just waits to handle messages, and because it's not performing word stuff at
this time, that maybe the COM object is getting GC'ed?

Is there a way for me to ping it (by using some timer or something) for me
to keep it going (if this is the case)?

What other workarounds do I have, or is this not the problem at all?

As an additional note: when this happens, if I click close on my Form - the
Word application (after several debugger exceptions about file not found
etc) - finally exits. So this tells me that my _thisApplication object (or
at least in this specific case - my WordAutomation instance) is still valid.

Any help would be greatly appreciated...

thanks - Fruber
 
H

Helmut Obertanner

Hello Fruber,

did you hold a reference to all of your buttons, or did you just add an
eventhandler and forget about the buttons ?

--
regards

Helmut Obertanner
Technical Consultant

Softwaredevelopment
DATALOG Software AG | Zschokkestr. 36 | D-80687 Munich
web: www.datalog.de


.... and IT works!
 
F

Fruber Malcome

I do not keep a reference to the button after I've added it (or created it
on the toolbar) - the same applies to the actual commandbar and menubar.

I assumed (and I'm wondering if this was incorrect) - that as I wouldn't
need to keep those references since I could always get them back by going
back to the commandbar (by accessing the docs commandbars) and then through
those controls.

Must I keep a reference of every control that I create? (in commandbars and
menubars)? I've never seen anyone perform this task - but maybe I wasn't
looking close enough?

Since I keep a structure of every control in an array - it wouldn't be too
difficult to provide an empty column in the array to hold the reference -
once it was created. (since these arrays are static members of the class)

Do you think that's causing my problem? Is there a way to prevent this
without holding a reference to every control (about 100 buttons).

Thanks - let me know what you are thinking?
Fruber
 
H

Helmut Obertanner

Hello Fruber,

i'm programming Outlook AddIns with C# and i had the same problems with
MenuBars and other objects.
I keep a reference to my CommandBar controls.
I didn't register every Button for the Click event.
Instead i register the CommandBar Click event and switch the Control Tag to
find out what Button was clicked.

However holding a reference to the Button is also much faster when you
access your Buttons.

Why not try it for some Buttons and see if this helps.
However, i beleive when you don't hold a reference to the buttons, the .Net
Garbage Collector removes the eventhandlers to your buttons when it does a
Memory-cleanup.
And therefore you don't get events from it.

--
regards

Helmut Obertanner
Technical Consultant

Softwaredevelopment
DATALOG Software AG | Zschokkestr. 36 | D-80687 Munich
web: www.datalog.de


.... and IT works!
 
F

Fruber Malcome

As a note, I did exactly what you did, one event handler and I use the tag
to determine what I need to-do.
So you keep a reference to the control where the event is directly tied to?

Since we both have used the same model - did you still see better
performance by keeping a reference to all your buttons - or just the
commandbar/menubar?

thanks - Fruber
 
H

Helmut Obertanner

Hello Fruber,

i keep a reference to all my Buttons, have only registered for the
CommandBar Click event.

If I can see a better performance ?
Thats a good question. However the way .Net accesses COM Objects has some
performance drawbacks.
So whenever you must find your CommandBarControls, the Code must work
through all objects, walk through .Net, Security checks, etc.etc.

I beleive it's faster to keep a reference.
The drawback is that you need some bytes of Memory and do a Cleanup.
But today that's not realy a problem.

--
regards

Helmut Obertanner
Technical Consultant

Softwaredevelopment
DATALOG Software AG | Zschokkestr. 36 | D-80687 Munich
web: www.datalog.de


.... and IT works!
 
F

Fruber Malcome

Ok, now I keep a reference to every control that I add, and I keep a
reference to the commandbar and menubar that I add.
I call the GC.Collect and everything sticks around for a lot longer.

It seems though that the events will fire and sometimes they won't.
(e.g. I'll click Help | About - then it'll work, I click it again, and it
will again, I click it again, it won't - giving me the error I had before,
I'll do this a few more times, and then it'll work again.!! )

Why would it not find the function (which I assume is what is really going
on) and then decide that it can't, then decide that it can. - all during the
same running instance??!!! - I know there's no such thing as random. But
what in the world is going on behind the scenes?

Am I better off with C++ on this - I NEVER had issues like this in C++.
What would make the code soo flaky? - It's only an application that handles
commandbar and menubar events - nothing special..

As a note - I never NEW any of the controls - since add provides a reference
back..

Thanks for the continued help.

thanks - bill
 
F

Fruber Malcome

Well it seems that it was randomly failing on my call to:
Thread.CurrentThread.Name = "".
Once I removed this line (and after adding references to all my controls) -
everything seems to be working.

Any reason why Thread.CurrentThread cause such a problem -within my handler?

thanks - Fruber
 
H

Helmut Obertanner

Hello Fruber,

sorry, no idea.
maybe it has something todo with the progid that you get in OnConnection
Event.

--
Freundliche Grüße / with regards

Helmut Obertanner
Technical Consultant

Softwaredevelopment
DATALOG Software AG | Zschokkestr. 36 | D-80687 Munich
web: www.datalog.de


.... and IT works!
 
F

Fruber Malcome

Now I've found myself in another pickle -

Now that I keep a reference to these objects - whenever a new document is
opened - my objects get set to these new instances.
(since I can have multple documents opened/closed/saved etc for this one
application instance - and since the commandbars do not (just show up on the
newly opened documents) - I have to re-create them..!

Any ideas on how to get around this? (short of creating an array of my class
objects - each tied to each document currently being used?)

thanks Fruber
 
H

Helmut Obertanner

Hello Fruber,

create a wrapperclass for your documents.
in this class create the Menus for each document.

--
Freundliche Grüße

Helmut Obertanner
Technical Consultant

Softwaredevelopment
DATALOG Software AG | Zschokkestr. 36 | D-80687 Munich
web: www.datalog.de


.... and IT works!
 
F

Fruber Malcome

That's what I finally did - and it worked.
Interestingly - I would have done this by default in c++, but I just didn't
think of it in C# - I didn't think it was necessary.
(shouldn't be lazy)

thanks - Fruber
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top