How to interrupt a managed thread blocked in unmanaged code?

I have a managed thread that waits, is blocked, in unmanaged code (in particular, it is called NamedPipeServerStream.WaitForConnection (), which ultimately calls the unmanaged code and does not offer a timeout).

I want to gently close the stream.

Thread.Abort () does not work until the code returns to a managed area, which will not be executed until the client makes a connection that we cannot wait).

I need a way to “shock” him from unmanaged code; or a way to just kill a thread, even when it is in unmanaged land.

+7
multithreading c #
source share
3 answers

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

using (NamedPipeServerStream stream = ...) { var asyncResult = stream.BeginWaitForConnection(null, null); if (asyncResult.AsyncWaitHandle.WaitOne(5000)) { stream.EndWaitForConnection(asyncResult); // success } } 

You do not have to use a fixed timeout. You can use ManualResetEvent to signal when a thread should stop waiting for a 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(); } 
+19
source share

It is impossible to "accurately" disconnect a stream from the outside if unrecognized code works in this stream. There are several ways to suddenly stop the flow, but this is probably not what you want.

Instead, use BeginWaitForConnection .

+1
source share

In fact, the solution I used (which occurred to me when I wrote the question) was to simply create (and immediately delete) the client for each thread after interrupting all the threads.

  threads.ForEach(thread=> thread.Abort()); threads.ForEach(thread=> { var client = new PipeClient(ServiceName); client.Connect(); client.Dispose(); }); 

When connected, it returns to the managed code, and Abort () starts (the thread captures ThreadAbortException and clears itself)

This does not work for the general case (i.e. the question asked in the header), but it works for me ...

0
source share

All Articles