How to unblock ConnectNamedPipe and ReadFile? [C#]
Asked Answered
L

3

7

I have a class (NamedPipeManager) which has a thread (PipeThread) that waits for a NamedPipe connection using (ConnectNamedPipe) and then reads (ReadFile) - these are blocking calls (not-overlapped) - however there comes a point when I want to unblock them - for example when the calling class tries to stop the NamedPipeManager...

How can I interupt it? Using Thread.abort? Thread.interrupt? Is there a proper way to handle this? Refer to the code below which illustrates my current situation

main()
{
    NamedPipeManager np = new NamedPipeManager();
        ... do stuff ...
    ... do stuff ...
    np.Stop();      // at this point I want to stop waiting on a connection
}


class NamedPipeManager
{
private Thread PipeThread;

public NamedPipeManager
{
    PipeThread = new Thread(new ThreadStart(ManagePipes));
    PipeThread.IsBackground = true;
    PipeThread.Name = "NamedPipe Manager";
    PipeThread.Start();
}

private void ManagePipes()
{
    handle = CreateNamedPipe(..., PIPE_WAIT, ...);
    ConnectNamedPipe(handle, null);     // this is the BLOCKING call waiting for client connection

    ReadFile(....);             // this is the BLOCKING call to readfile after a connection has been established
    }


public void Stop()
{
    /// This is where I need to do my magic
    /// But somehow I need to stop PipeThread
    PipeThread.abort();     //?? my gut tells me this is bad
}
};

So, in function Stop() - how would I gracefully unblock the call to ConnectNamedPipe(...) or ReadFile(...)?

Any help would be appreciated. Thanks,

Lunneta answered 30/8, 2009 at 6:45 Comment(0)
D
6

Starting with Windows Vista, there is a CancelSynchronousIO operation available for threads. I don't think there is a C# wrapper for it, so you would need to use PInvoke to call it.

Before Vista, there isn't really a way to perform such an operation gracefully. I would advise against using thread cancellation (which might work, but doesn't qualify as graceful). Your best approach is to use overlapped IO.

Dunt answered 30/8, 2009 at 6:59 Comment(4)
Does this apply to both cases (ConnectNamedPipe & ReadFile)? I can find a way to get past ConnectNamedPipe by faking a connection which will unblock it and then exit (based on a bool) - but I can't see how I can unblock a ReadFile ever ... How is this usually done? There has to be some non-asynch way of handling this situation.Lunneta
BTW - this is to run on Windows 2000 and XP ... no Vista anytime soon .. Also using .Net 2.0 ... Thanks,Lunneta
One way would be to specify a time-out on all operations, and then essentially perform polling (i.e. perform a read operation for, say, 1s, then check whether the thread should abort, if not, continue reading). However, it seems that Microsoft really doesn't believe in timeouts, so there is no API to specify them. See also #593675Chromolithograph
So then my only choice is Thread.Abort? I can't use I/O because the client (old C++) isn't ... which caused issues - had to use synch.Lunneta
I
7

It seems to be working on VC6.0, WinXP if I try to interrupt ConnectNamedPipe by DeleteFile("\\\\.\\pipe\\yourpipehere");

So just specify name, not handle.

Idomeneus answered 21/10, 2011 at 8:58 Comment(2)
In fact, DeleteFile internally opens file handle by name, so this is equivalent to calling CreateFile().Annunciata
@IvanShcherbakov does this mean that ConnectNamedPipe is unblocked simply because DeleteFile makes a connection?Attitude
D
6

Starting with Windows Vista, there is a CancelSynchronousIO operation available for threads. I don't think there is a C# wrapper for it, so you would need to use PInvoke to call it.

Before Vista, there isn't really a way to perform such an operation gracefully. I would advise against using thread cancellation (which might work, but doesn't qualify as graceful). Your best approach is to use overlapped IO.

Dunt answered 30/8, 2009 at 6:59 Comment(4)
Does this apply to both cases (ConnectNamedPipe & ReadFile)? I can find a way to get past ConnectNamedPipe by faking a connection which will unblock it and then exit (based on a bool) - but I can't see how I can unblock a ReadFile ever ... How is this usually done? There has to be some non-asynch way of handling this situation.Lunneta
BTW - this is to run on Windows 2000 and XP ... no Vista anytime soon .. Also using .Net 2.0 ... Thanks,Lunneta
One way would be to specify a time-out on all operations, and then essentially perform polling (i.e. perform a read operation for, say, 1s, then check whether the thread should abort, if not, continue reading). However, it seems that Microsoft really doesn't believe in timeouts, so there is no API to specify them. See also #593675Chromolithograph
So then my only choice is Thread.Abort? I can't use I/O because the client (old C++) isn't ... which caused issues - had to use synch.Lunneta
K
0

Recently I was in a situation, I could not use the Async Overlapped IO. I was stuck on the server side within ConnectNamedPipe. To unlock the thread and free resources, I had to connect to the same pipe as a client for a split second.

  1. Main thread receives the stop signal
  2. Main thread sets the stop event for the listening thread
  3. Main thread connects to the pipe
  4. If succeeded (always) - closes the newly created handle immediately

  1. Listener thread unlocks
  2. Listener thread does whatever required

This worked for me very well.

To unblock ReadFile one needs to connect and write to the pipe. Same effect epected.

Kunin answered 17/5, 2022 at 10:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.