c# - Async NamedPipes in case of multiple pipe server instances -
i'm using code this article difference maxnumberofserverinstances set -1 (number of server instances same pipe name limited system resources) in namedpipeserverstream constructor
async listen method [listen server class]:
class pipeserver { string _pipename; public void listen(string pipename) { try { // set class level var can re-use in async callback method _pipename = pipename; // create new async pipe namedpipeserverstream pipeserver = new namedpipeserverstream(pipename, pipedirection.in, -1, pipetransmissionmode.byte, pipeoptions.asynchronous); // wait connection pipeserver.beginwaitforconnection (new asynccallback(waitforconnectioncallback), pipeserver); } catch (exception oex) { ... } } private void waitforconnectioncallback(iasyncresult iar) { try { // pipe namedpipeserverstream pipeserver = (namedpipeserverstream)iar.asyncstate; // end waiting connection pipeserver.endwaitforconnection(iar); // read incoming message byte[] buffer = new byte[255]; pipeserver.read(buffer, 0, 255); // convert byte buffer string string stringdata = encoding.utf8.getstring(buffer, 0, buffer.length); ... // kill original sever , create new wait server pipeserver.close(); pipeserver = null; pipeserver = new namedpipeserverstream(_pipename, pipedirection.in, -1, pipetransmissionmode.byte, pipeoptions.asynchronous); // recursively wait connection again , again.... pipeserver.beginwaitforconnection( new asynccallback(waitforconnectioncallback), pipeserver); } catch { ... } } } async send method [pipeclient class]
class pipeclient { public void send(string sendstr, string pipename, int timeout = 1000) { try { namedpipeclientstream pipestream = new namedpipeclientstream (".", pipename, pipedirection.out, pipeoptions.asynchronous); // connect function indefinitely wait pipe become available // if not acceptable specify maximum waiting time (in ms) pipestream.connect(timeout); byte[] _buffer = encoding.utf8.getbytes(sendstr); pipestream.beginwrite (_buffer, 0, _buffer.length, new asynccallback(asyncsend), pipestream); } catch (timeoutexception oex) { ... } } private void asyncsend(iasyncresult iar) { try { // pipe namedpipeclientstream pipestream = (namedpipeclientstream)iar.asyncstate; // end write pipestream.endwrite(iar); pipestream.flush(); pipestream.close(); pipestream.dispose(); } catch (exception oex) { ... } } } and have 2 winforms applications: server have listen button (clicking results in listen method call), client has textbox text input , send button (clicking results in send method call).
i following:
- start multiple copies of server application (as result - multiple instances of namedpipeserverstream same pipe name created)
- click listen button in each of them
- start client application
- click send button
that results in receiving message only 1 server application (that one, listen button clicked first). if click send button 1 more time - message received second-clicked server application. instances receive messages in order of pressing listen button on them , repeats in cycle (but i'm not 100% sure such order will same under conditions).
such behavior strange me: i've expected message received all instances @ same time.
could explain me why happening in such way?
how can deliver message instaces 1 send button click?
so i've found solution (don't sure it's optimal - it's working). based on using namedpipeclientstream.numberofserverinstances.
public void send(string sendstr, string pipename, int timeout = 1000) { try { namedpipeclientstream pipestream = new namedpipeclientstream (".", pipename, pipedirection.out, pipeoptions.asynchronous); // connect function indefinitely wait pipe become available // if not acceptable specify maximum waiting time (in ms) pipestream.connect(timeout); int _servercount = pipestream.numberofserverinstances; byte[] _buffer = encoding.utf8.getbytes(sendstr); pipestream.beginwrite(_buffer, 0, _buffer.length, new asynccallback(asyncsend), pipestream); //there more 1 server present (int = 1; < _servercount; i++) { //create client copy , use namedpipeclientstream pipestream2 = new namedpipeclientstream (".", pipename, pipedirection.out, pipeoptions.asynchronous); pipestream2.connect(timeout); byte[] buffer2 = encoding.utf8.getbytes(sendstr); pipestream2.beginwrite(buffer2, 0, buffer2.length, asyncsend, pipestream2); } } catch (timeoutexception oex) { ... } } note code doensn't handle situation when numberofserverinstances changes while cycle running (sudden server instance closing, etc.)
btw don't have idea why msdn suggests use
// kill original sever , create new wait server pipeserver.close(); pipeserver = null; pipeserver = new namedpipeserverstream(_pipename, pipedirection.in, -1, pipetransmissionmode.byte, pipeoptions.asynchronous); // recursively wait connection again , again.... pipeserver.beginwaitforconnection( new asynccallback(waitforconnectioncallback), pipeserver); instead i've tested disconnecting current client
pipeserver.disconnect(); // recursively wait connection again , again.... pipeserver.beginwaitforconnection( new asynccallback(waitforconnectioncallback), pipeserver); and worked me same way.
rofl what a worthless article. Sure like all the source code for download rofl
ReplyDeleteNice copy and paste article