How to kill a thread blocked on an interop call?

  • Thread starter Christopher Carnahan
  • Start date
C

Christopher Carnahan

I need to figure out how to terminate a thread while it is blocked trying to
create a COM object via interop.

In a worker thread, I do something like this:

Type t = null;
Object activatedObject = null;
Legacy.IScheduled comObject = null;

t = Type.GetTypeFromProgID(ProgID);
activatedObject = Activator.CreateInstance(t);
comObject = (Legacy.IScheduled) activatedObject;
t.InvokeMember("Execute", BindingFlags.InvokeMethod, null,
activatedObject,
while (Marshal.ReleaseComObject(comObject) > 0);
comObject = null;
while (Marshal.ReleaseComObject(activatedObject) > 0);
activatedObject = null;

But the COM object I am calling is an out-of-process COM server written in
VB. If the .exe is busy or hung, the call to Activator.CreateInstance never
returns. I need to kill the worker thread if it hangs on this line, but
Thread.Abort doesn't work, since the ThreadAbortException isn't raised while
the thread is busy.

In .Net 1.1, I did this:

Thread t = new Thread(new ThreadStart(_thread.Abort));
t.Start();

Thread.Sleep(1000);

if (null != _thread)
{
_thread.Abort();
_thread = null;
}

_thread is the worker thread I need to kill. I spawned off a new thread
that called abort on the worker thread, waited a second, and called abort
from the main thread. This is super ugly, but it seemed to work, because
the worker thread would die. But when I recompiled my code for .Net 2.0,
this quit working. The call to _thread.Abort never returns, presumably
because it is blocking, waiting for the worker thread to stop blocking on
the call to the Activator.

So, any ideas how to do this? What I really need is a timeout mechanism on
the call to Activator.CreateInstance, but there isn't one. Is there another
way to approach this? I could convert the worker thread to a worker
process, and just kill the process, or do something with AppDomains, but I
was hoping for a less dramatic solution. Thoughts?

- Christopher
 
M

mnisiuk

Christopher said:
I need to figure out how to terminate a thread while it is blocked trying to
create a COM object via interop.

In a worker thread, I do something like this:

Type t = null;
Object activatedObject = null;
Legacy.IScheduled comObject = null;

t = Type.GetTypeFromProgID(ProgID);
activatedObject = Activator.CreateInstance(t);
comObject = (Legacy.IScheduled) activatedObject;
t.InvokeMember("Execute", BindingFlags.InvokeMethod, null,
activatedObject,
while (Marshal.ReleaseComObject(comObject) > 0);
comObject = null;
while (Marshal.ReleaseComObject(activatedObject) > 0);
activatedObject = null;

But the COM object I am calling is an out-of-process COM server written in
VB. If the .exe is busy or hung, the call to Activator.CreateInstance never
returns. I need to kill the worker thread if it hangs on this line, but
Thread.Abort doesn't work, since the ThreadAbortException isn't raised while
the thread is busy.

In .Net 1.1, I did this:

Thread t = new Thread(new ThreadStart(_thread.Abort));
t.Start();

Thread.Sleep(1000);

if (null != _thread)
{
_thread.Abort();
_thread = null;
}

_thread is the worker thread I need to kill. I spawned off a new thread
that called abort on the worker thread, waited a second, and called abort
from the main thread. This is super ugly, but it seemed to work, because
the worker thread would die. But when I recompiled my code for .Net 2.0,
this quit working. The call to _thread.Abort never returns, presumably
because it is blocking, waiting for the worker thread to stop blocking on
the call to the Activator.

So, any ideas how to do this? What I really need is a timeout mechanism on
the call to Activator.CreateInstance, but there isn't one. Is there another
way to approach this? I could convert the worker thread to a worker
process, and just kill the process, or do something with AppDomains, but I
was hoping for a less dramatic solution. Thoughts?

- Christopher
You could try calling Thread.Interrupt. But I'm not sure if the
Interrupt() will work in unmanaged code.
 
W

Willy Denoyette [MVP]

|I need to figure out how to terminate a thread while it is blocked trying
to
| create a COM object via interop.
|
| In a worker thread, I do something like this:
|
| Type t = null;
| Object activatedObject = null;
| Legacy.IScheduled comObject = null;
|
| t = Type.GetTypeFromProgID(ProgID);
| activatedObject = Activator.CreateInstance(t);
| comObject = (Legacy.IScheduled) activatedObject;
| t.InvokeMember("Execute", BindingFlags.InvokeMethod, null,
| activatedObject,
| while (Marshal.ReleaseComObject(comObject) > 0);
| comObject = null;
| while (Marshal.ReleaseComObject(activatedObject) > 0);
| activatedObject = null;
|
| But the COM object I am calling is an out-of-process COM server written in
| VB. If the .exe is busy or hung, the call to Activator.CreateInstance
never
| returns. I need to kill the worker thread if it hangs on this line, but
| Thread.Abort doesn't work, since the ThreadAbortException isn't raised
while
| the thread is busy.
|
| In .Net 1.1, I did this:
|
| Thread t = new Thread(new ThreadStart(_thread.Abort));
| t.Start();
|
| Thread.Sleep(1000);
|
| if (null != _thread)
| {
| _thread.Abort();
| _thread = null;
| }
|
| _thread is the worker thread I need to kill. I spawned off a new thread
| that called abort on the worker thread, waited a second, and called abort
| from the main thread. This is super ugly, but it seemed to work, because
| the worker thread would die. But when I recompiled my code for .Net 2.0,
| this quit working. The call to _thread.Abort never returns, presumably
| because it is blocking, waiting for the worker thread to stop blocking on
| the call to the Activator.
|
| So, any ideas how to do this? What I really need is a timeout mechanism
on
| the call to Activator.CreateInstance, but there isn't one. Is there
another
| way to approach this? I could convert the worker thread to a worker
| process, and just kill the process, or do something with AppDomains, but I
| was hoping for a less dramatic solution. Thoughts?
|
| - Christopher

A thread that currently blocks in unmanaged code cannot be aborted by
Thread.Abort, this was so in V1 and is still the same in V2, so I assume
that the thread wasn't really blocking when it "worked" on V1.
All you can do is terminate the process, or better try to fix the out-proc
server, servers that block indefinitely are broken, it's not up to the
caller process (the client) to fix it.


Willy.
 

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