Discussion:
Working with named pipes
(too old to reply)
Anton Shepelev
2016-04-22 12:03:33 UTC
Permalink
Hello, all

I have a primitive named-pipe server using synchronious IO.
When my listening thread is frozen at a synchronious call to
ConnectNamedPipe() from kernel32.dll, the thread.Abort()
method seems to have no effect. Is it the expected behavour
and does it mean that one must always use ahynchronous pipe
operations in C#?
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Marcel Mueller
2016-04-22 16:27:20 UTC
Permalink
Post by Anton Shepelev
I have a primitive named-pipe server using synchronious IO.
When my listening thread is frozen at a synchronious call to
ConnectNamedPipe() from kernel32.dll, the thread.Abort()
method seems to have no effect.
Do not use Thread.Abort(). It almost never does what you want.
Post by Anton Shepelev
Is it the expected behavour
and does it mean that one must always use ahynchronous pipe
operations in C#?
AFAIK Thread.Abort injects a ThreadAbortException into the other thread
which is obviously impossible while executing native kernel code.

You should close the pipe handle instead. (Didn't test this in C#.)


Marcel
Anton Shepelev
2016-04-22 19:20:42 UTC
Permalink
Post by Anton Shepelev
I have a primitive named-pipe server using synchronious
IO. When my listening thread is frozen at a
synchronious call to ConnectNamedPipe() from
kernel32.dll, the thread.Abort() method seems to have no
effect. Is it the expected behavour and does it mean
that one must always use ahynchronous pipe operations in
C#?
Do not use Thread.Abort(). It almost never does what you
want.
That's true, but my program is a yet a prototype, and I have
deinitilization in the catch{} clause.
Post by Anton Shepelev
Is it the expected behavour and does it mean that one
must always use ahynchronous pipe operations in C#?
AFAIK Thread.Abort injects a ThreadAbortException into the
other thread ->
That's right.
-> which is obviously impossible while executing native
kernel code. You should close the pipe handle instead.
(Didn't test this in C#.)
Hmmm. Do you mean closing the handle from another thread,
i.e. from which I want to initiate the termination of the
listener thread containing the kernel calls?
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Marcel Mueller
2016-04-23 08:31:22 UTC
Permalink
Post by Anton Shepelev
Hmmm. Do you mean closing the handle from another thread,
i.e. from which I want to initiate the termination of the
listener thread containing the kernel calls?
Exactly. This is a common way using native APIs. You receive an error
code in this case which is probably transformed to an IOException by the
C# runtime.

From the documentation doing so is not allowed since instance methods
like Close are not thread safe. I am a bit unsure whether this is true.
Maybe only the documentation is not exact enough.
See response from Kim Hamilton (BCL team):
"The "right" way to do an interruptible WaitForConnection is to call
BeginWaitForConnection, handle the new connection in the callback, and
close the pipe stream to stop waiting for connections. If the pipe is
closed, EndWaitForConnection will throw ObjectDisposedException which
the callback thread can catch, clean up any loose ends, and exit cleanly."

The official way with newer Frameworks is
WaitForConnectionAsync(CancellationToken). Seems that they use the
overlapped IO feature of the kernel. Unfortunately the implementation of
CancelIoEx is in the C core.
Anton Shepelev
2016-04-25 10:54:37 UTC
Permalink
Post by Marcel Mueller
Do you mean closing the handle from another thread, i.e.
from which I want to initiate the termination of the
listener thread containing the kernel calls?
Exactly. This is a common way using native APIs. You
receive an error code in this case which is probably
transformed to an IOException by the C# runtime.
From the documentation doing so is not allowed since
instance methods like Close are not thread safe. I am a
bit unsure whether this is true. Maybe only the
documentation is not exact enough. See response from Kim
Hamilton (BCL team): "The "right" way to do an
interruptible WaitForConnection is to call
BeginWaitForConnection, handle the new connection in the
callback, and close the pipe stream to stop waiting for
connections. If the pipe is closed, EndWaitForConnection
will throw ObjectDisposedException which the callback
thread can catch, clean up any loose ends, and exit
cleanly."
The official way with newer Frameworks is
WaitForConnectionAsync(CancellationToken). Seems that
they use the overlapped IO feature of the kernel.
Unfortunately the implementation of CancelIoEx is in the C
core.
Thanks, but all this seems related to the high-level .NET
NamedPipeServerStream class, which I do not use. There is
another answer at StackOverflow, advising the programmer to
terminate the call to ConnectNamedPipe() by actually
creating a dummy connection. I belive it is even better
than deleting the pipe "file" because it will let an
existing session to complete normally.
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Anton Shepelev
2016-04-25 10:40:52 UTC
Permalink
Post by Marcel Mueller
Post by Anton Shepelev
I have a primitive named-pipe server using synchronious
IO. When my listening thread is frozen at a
synchronious call to ConnectNamedPipe() from
kernel32.dll, the thread.Abort() method seems to have no
effect. Is it the expected behavour and does it mean
that one must always use ahynchronous pipe operations in
C#?
You should close the pipe handle instead. (Didn't test
this in C#.)
Calling CloseHandle() in the control thread does not
terminate the call to ConnectNamedPipe() in the listener
thread but freezes itself. Trying to delete the file with
the name of the pipe, however, helps.
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Anton Shepelev
2016-05-18 11:33:00 UTC
Permalink
I have a primitive named-pipe server using synchro-
nious IO. When my listening thread is frozen at a
synchronious call to ConnectNamedPipe() from ker-
nel32.dll, the thread.Abort() method seems to have no
effect. Is it the expected behavour and does it mean
that one must always use ahynchronous pipe operations
in C#?
By way of a belated report, I shall tell that my solu-
tion was to switch to so-called "Overlapped IO". Al-
though more complicated in terms of native calls, it
provides a way gracefully to terminate existing listen-
ers, which wait for a connection with a timeout in a
loop checking on a flag after every timeout.
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
Continue reading on narkive:
Loading...