VB6 AddIn background activity + user typing hangs Outlook 2007

  • Thread starter Thread starter Mark McGinty
  • Start date Start date
M

Mark McGinty

Our VB6 AddIn uses timers on an invisible form to drive background
processing -- a good deal of which involves MSXML.XMLHttpRequest, called
asynchronously.

The background processing itself doesn't cause any problems, I have had a
virtual running for days with a very short interval for background tasks,
and with multiple inspectors left open -- it has yet to hang. On an
identical virtual, while typing in an email body as I normaly do when
composing, I have seen Outlook hang numerous times. For all occurrences,
background processing was underway when it hung.

Google returns countless reports of a similar nature, but I have yet to see
mention of a solution, nor even an exact cause.

Has anyone else seen anything similar? If so, any resolution? I keep
seeing statements by various MVPs about "compatible" AddIns (some even
suggest using only AddIns developed by Microsoft -- which is pure BS if you
ask me.) Is there any spec for Outlook 2007 AddIn compatibility? Any idea
what the 2007 email editor is doing that is so intolerant of AddIns doing
things behind the scenes?


TIA,
Mark

btw, yes this is somewhat a repost of an earlier question, I wanted the
subject to more accurately reflect the problem.
 
Is the background process doing anything with the Outlook object model?
Outlook is designed so that all accesses to the object model must be on the
main thread and especially with VB 6 if a background thread calls into the
object model that will crash Outlook (more with Outlook 2007) or hang it
(more with Outlook 2003 or earlier). Could something like that be the
problem?

I do a lot of background processing with many of my addins and haven't see
the hang problem you describe unless the object model is being used there.

I have seen and heard of quite a few hang problems with Outlook 2007 related
to working with the object model even on the main thread when typing in the
body of an email. What I haven't see are any clean repros (that sort of
thing never yet has happened here on any of my Office 2007 setups for
example) or good explanations of why it's happening.

Some theories are that too many RSS feeds can be implicated, background
indexing of Outlook items for WDS is another possibility, as is a setting
for doing send/receives with too short an interval.

I've had reports from members of the Outlook product group that the same
thing has happened with them with no addins running, so while this may not
help it may not be the fault of your addin at all.
 
Thanks for the informative reply, Ken, see responses inline...


Ken Slovak - said:
Is the background process doing anything with the Outlook object model?

Other than creating/deleting/locating/changing contact, task and appointment
items, no not especially. :-)
Outlook is designed so that all accesses to the object model must be on
the main thread and especially with VB 6 if a background thread calls into
the object model that will crash Outlook (more with Outlook 2007) or hang
it (more with Outlook 2003 or earlier). Could something like that be the
problem?

It hasn't been a problem until Outlook 2007 came along... OOM isn't
thread-safe within Outlook's process space? I could understand (and even
expect) individual objects being non-thread-safe, but the entire model needs
to execute in a single thread? Is that documented anywhere?

Out of curiosity I added a call to GetCurrentThreadID to my debugging
output. Apparently all OOM events *and* all of my timer controls' Timer
events -- they all execute on the same thread! My async XMLHttpRequest
calls must surely cause creation of a new thread, but I poll the readystate
of that object (it's event is unreliable) so even my accesses to that
*should* execute on Outlook's single chosen thread...

I do a lot of background processing with many of my addins and haven't see
the hang problem you describe unless the object model is being used there.

I have seen and heard of quite a few hang problems with Outlook 2007
related to working with the object model even on the main thread when
typing in the body of an email. What I haven't see are any clean repros
(that sort of thing never yet has happened here on any of my Office 2007
setups for example) or good explanations of why it's happening.

Hmm, I just might be able to create that nice clean repro...

This is getting very interesting.

More to follow...


-Mark
 
Mark McGinty said:
Thanks for the informative reply, Ken, see responses inline...




Other than creating/deleting/locating/changing contact, task and
appointment items, no not especially. :-)


It hasn't been a problem until Outlook 2007 came along... OOM isn't
thread-safe within Outlook's process space? I could understand (and even
expect) individual objects being non-thread-safe, but the entire model
needs to execute in a single thread? Is that documented anywhere?

Out of curiosity I added a call to GetCurrentThreadID to my debugging
output. Apparently all OOM events *and* all of my timer controls' Timer
events -- they all execute on the same thread! My async XMLHttpRequest
calls must surely cause creation of a new thread, but I poll the
readystate of that object (it's event is unreliable) so even my accesses
to that *should* execute on Outlook's single chosen thread...



Hmm, I just might be able to create that nice clean repro...

This is getting very interesting.

More to follow...


-Mark

I compiled our AddIn with debugging info, and downloaded all the debugging
symbols for the system, to facilitate useful debugging with VS 2005, of
Outlook's process after it hung. This helped me to definitively isolate the
problem construct, in only a few painful but bearable hours. :-)

It appears that the problem -- or, at least, one manifestation of it -- is
caused by calling DoEvents, particularly in a loop (which, of course,
substantially ups the odds of it being called at exactly the wrong time.)

My Addin calls DoEvents 103 times, I've made a point of calling it in
practically every single loop, to minimize the UI impact of background
processing/make user cancellation possible. I guess we'll have to forego
that nicety under Outlook 2007.

As for the threadedness of background processing, I found (by outputting the
ThreadID of the current thread in every debug output) that every single
thing my AddIn does, is always called on the same thread, be it OOM events,
timer events on hidden forms -- everything. I can't say it's impossible in
VB6 to execute [in-proc] background processing on some other thread, but
from what I've seen it surely doesn't happen by accident. (Use of out-proc
COM servers excepted.)

In any case, OOM object access was not implicated in any of the AddIn's
post-hang callstacks I trapped into -- in this case all of them were
enumerating XML object collections. (Most of the loops that do so in this
code are fairly tight, which may serve to explain the behavior upon which my
observations were based.)

Unfortunately I don't have any simple, clean repro code to share [yet], but
I was able to reproduce the condition consistently, like ringing a bell,
running our [arguably somewhat convoluted] AddIn code. I will try to pare
it down to something simple enough to publish here, as time permits.


-Mark
 
Is it possible that in any of your loops where you call DoEvents that the
loop could be re-entrant? Any possible UI actions that could be taken to
cause one of the loops to be entered again possibly?

I use DoEvents myself in many loops that do a lot of processing to both cede
cycles and to prime the Windows message pump and to present a semblance of
responsiveness. So it's possible that where the problem is seen in my addins
is due to DoEvents, although I'm very careful to make sure my loops aren't
re-entrant. But one never knows, do one?

I do know that in .NET code that when you try to get a synchronization
context for the main Outlook thread you can't get the context unless you
first prime the message pump by calling DoEvents, I've run into that one.
But VB 6 code doesn't have that bump in the road.

I'll have to play here with commenting out DoEvents calls in my timer
activated loops and see if that does anything to remove the problem for my
users who see Outlook 2007 hangs when typing in item bodies.




I compiled our AddIn with debugging info, and downloaded all the debugging
symbols for the system, to facilitate useful debugging with VS 2005, of
Outlook's process after it hung. This helped me to definitively isolate
the problem construct, in only a few painful but bearable hours. :-)

It appears that the problem -- or, at least, one manifestation of it -- is
caused by calling DoEvents, particularly in a loop (which, of course,
substantially ups the odds of it being called at exactly the wrong time.)

My Addin calls DoEvents 103 times, I've made a point of calling it in
practically every single loop, to minimize the UI impact of background
processing/make user cancellation possible. I guess we'll have to forego
that nicety under Outlook 2007.

As for the threadedness of background processing, I found (by outputting
the ThreadID of the current thread in every debug output) that every
single thing my AddIn does, is always called on the same thread, be it OOM
events, timer events on hidden forms -- everything. I can't say it's
impossible in VB6 to execute [in-proc] background processing on some other
thread, but from what I've seen it surely doesn't happen by accident.
(Use of out-proc COM servers excepted.)

In any case, OOM object access was not implicated in any of the AddIn's
post-hang callstacks I trapped into -- in this case all of them were
enumerating XML object collections. (Most of the loops that do so in this
code are fairly tight, which may serve to explain the behavior upon which
my observations were based.)

Unfortunately I don't have any simple, clean repro code to share [yet],
but I was able to reproduce the condition consistently, like ringing a
bell, running our [arguably somewhat convoluted] AddIn code. I will try
to pare it down to something simple enough to publish here, as time
permits.


-Mark
 
Ken Slovak - said:
Is it possible that in any of your loops where you call DoEvents that the
loop could be re-entrant? Any possible UI actions that could be taken to
cause one of the loops to be entered again possibly?

Hmm... nothing is impossible, but in this case I'd say the possibility is
extremely remote.
I use DoEvents myself in many loops that do a lot of processing to both
cede cycles and to prime the Windows message pump and to present a
semblance of responsiveness. So it's possible that where the problem is
seen in my addins is due to DoEvents, although I'm very careful to make
sure my loops aren't re-entrant. But one never knows, do one?

I do know that in .NET code that when you try to get a synchronization
context for the main Outlook thread you can't get the context unless you
first prime the message pump by calling DoEvents, I've run into that one.
But VB 6 code doesn't have that bump in the road.

I'll have to play here with commenting out DoEvents calls in my timer
activated loops and see if that does anything to remove the problem for my
users who see Outlook 2007 hangs when typing in item bodies.

I created a wrapper function called DoEventsEx and replaced all occurrences
of DoEvents with that. Initially it was just a no-op, but then I changed it
to conditionally call DoEvents based on Outlook version. (This project has
103 calls to DoEvents, so I figured the infantessimal amount of function
call overhead was an equitable trade-off.) :-)

My long-range plan is to move most of the processing out of Outlook's thread
0, and into out-proc COM objects. Outlook is a convenient and intuitive
place to manage launching these processes, it's all very Outlook-centric.
But I see little advantage, if any at all, to running them in-proc. So
someday in the future my AddIns will concern themselves only with extending
Outlook's UI to suit needs, and launching top-level processes out of
process. At that point, in theory anyway, this issue will become moot.

-Mark

I compiled our AddIn with debugging info, and downloaded all the
debugging symbols for the system, to facilitate useful debugging with VS
2005, of Outlook's process after it hung. This helped me to definitively
isolate the problem construct, in only a few painful but bearable hours.
:-)

It appears that the problem -- or, at least, one manifestation of it --
is caused by calling DoEvents, particularly in a loop (which, of course,
substantially ups the odds of it being called at exactly the wrong time.)

My Addin calls DoEvents 103 times, I've made a point of calling it in
practically every single loop, to minimize the UI impact of background
processing/make user cancellation possible. I guess we'll have to forego
that nicety under Outlook 2007.

As for the threadedness of background processing, I found (by outputting
the ThreadID of the current thread in every debug output) that every
single thing my AddIn does, is always called on the same thread, be it
OOM events, timer events on hidden forms -- everything. I can't say it's
impossible in VB6 to execute [in-proc] background processing on some
other thread, but from what I've seen it surely doesn't happen by
accident. (Use of out-proc COM servers excepted.)

In any case, OOM object access was not implicated in any of the AddIn's
post-hang callstacks I trapped into -- in this case all of them were
enumerating XML object collections. (Most of the loops that do so in
this code are fairly tight, which may serve to explain the behavior upon
which my observations were based.)

Unfortunately I don't have any simple, clean repro code to share [yet],
but I was able to reproduce the condition consistently, like ringing a
bell, running our [arguably somewhat convoluted] AddIn code. I will try
to pare it down to something simple enough to publish here, as time
permits.


-Mark
 
Back
Top