Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to terminate a managed thread blocked in unmanaged code?

I have a managed thread which is waiting, blocked, in an unmanaged code (specifically, it on a call to NamedPipeServerStream.WaitForConnection() which ultimitely calls into unmanaged code, and does not offer a timeout).

I want to shut the thread down neatly.

Thread.Abort() has no effect until the code returns to the managed realm, which it won't do until a client makes a connection, which we can't wait for).

I need a way "shock" it out of the unmanaged code; or a way to just kill the thread even while it's in unmanaged land.

like image 226
James Curran Avatar asked Apr 23 '10 17:04

James Curran


2 Answers

Have you tried using the non-blocking NamedPipeServerStream.BeginWaitForConnection method?

using (NamedPipeServerStream stream = ...)
{
    var asyncResult = stream.BeginWaitForConnection(null, null);

    if (asyncResult.AsyncWaitHandle.WaitOne(5000))
    {
        stream.EndWaitForConnection(asyncResult);
        // success
    }
}

You don't necessarily have to use a fixed timeout. You can use a ManualResetEvent to signal when the thread should stop waiting for the connection:

ManualResetEvent signal = new ManualResetEvent(false);

using (NamedPipeServerStream stream = ...)
{
    var asyncResult = stream.BeginWaitForConnection(_ => signal.Set(), null);

    signal.WaitOne();
    if (asyncResult.IsCompleted)
    {
        stream.EndWaitForConnection(asyncResult);
        // success
    }
}

// in other thread
void cancel_Click(object sender, EventArgs e)
{
    signal.Set();
}
like image 140
dtb Avatar answered Nov 10 '22 00:11

dtb


There is no way to "neatly" shut down a thread from the outside, if that thread is running unmannaged code. There are a couple of ways to abruptly Terminate the thread, but that's probably not what you want.

You should use BeginWaitForConnection instead.

like image 28
Jeffrey L Whitledge Avatar answered Nov 09 '22 23:11

Jeffrey L Whitledge