Passing content outside of an asynchronous server socket - c#

I'm not even sure how this would work because at its very nature an asynchronous server socket can accept multiple connections.
What I would like to do is capture content if it meets a certain format and pass it outside the server socket so that other classes can reference it. I followed the MSDN code for building a Asynchronous Server Socket. Here is the callback that reads the content.
public static void ReadCallback(IAsyncResult ar)
{
string content = String.Empty;
// Retrieve the state object and the handler socketH:\JCI\BWSI\Integrations\Middleware\Jci\Jci\Framework.Jci.EventEngine\EventEngineRTLSEvents.cs
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data recieved so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read more data.
content = state.sb.ToString();
if (content.IndexOf('\u001c') > -1)
{
// ALl the data has been read from the
// client. Display it on the console.
Console.WriteLine(
"Read {0} bytes from socket. \n Data : {1}", content.Length, content);
// Echo the data back to the client.
Send(handler, content);
}
else
{
// Not all data recieived. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}

If I understand the question correctly, the basic issue is this: when some data is received on the socket, that results in some new object being created in your program, and you want some code to operate on this object to process it in some way.
So, let's think about it this way: when you want some code to execute, how do you make that happen? Since in C# all code exists in methods, you need to call a method to make the code execute.
Now, in the scenario of an asynchronously handled socket, you have some options. Code always executes in the context of a thread, so you need to think about which thread you want to execute this particular code. That really amounts to there being just two options: 1) execute in the current thread, or 2) execute in a different thread.
Okay, now we're getting somewhere. If we pick option #1, how does that happen? Easy...just call the method from your ReadCallback() method. If you've created an object you want that called method to process, just pass that object to the method when you call it.
And it really is that simple (*).
Now, what if you want to pick #2? Well…that's a bit more complicated. First, you need to find a thread to execute the code, and second you need to get the data to that thread.
I can think of at least three obvious ways to go about this:
Use an existing UI thread. In this case, you'll use e.g. the Control.Invoke() method or Dispatcher.Invoke() (for Winforms or WPF, respectively). A similar mechanism is available in ASP.NET.
Use the thread pool, e.g. via the Task Parallel Library. For example, you might use the Task.Run() method to start a new task.
Use a producer/consumer implementation, in which you've previously started a thread dedicated just to consuming the data objects created when receiving data. For example, you could start a new thread with a method that just uses foreach to pull items from a BlockingCollection<T> instance, while the ReadCallback() method adds items to that same instance.
In the first two options above, data moves to the other thread via an argument to the method being invoked, or as a captured variable in an anonymous method being invoked (I find the latter more convenient than the former, but either works fine). In the third option, obviously the data moves from the socket's thread to the consuming thread via the shared collection.
I hope that the above is enough to get you pointed in the right direction. As asked, the question is fairly broad (possibly too broad), but I think what I've written here is still reasonably concise, with just enough vagueness to remain applicable to whatever your scenario is, without being so vague as to be non-useful. :)
(*) Actually, it's a little more complicated than that, in that you have a number of mechanisms by which you can call a method. The simplest is that the method name is hard-coded into your ReadCallback() method; you just call the one method you know you always want to call. But that limits reusability of the code, and couples it to unrelated code which makes it harder to maintain.
Other options include:
Declaring an event on your socket client object where the ReadCallback() method exists, and have the object that's supposed to actually process the data subscribe to that event. The ReadCallback() method would raise the event, passing the object to process as part of the event's arguments.
Simply passing a callback delegate to the socket client object, very much in the same way you currently pass a delegate representing your ReadCallback() method to the socket class.

First off, this is not really intended to be an answer, but I find that writing a lot of text as comments is problematic.
I've now actually taken a look at your code, and maybe I'm beginning to understand what you're asking. Your use of the phrase "pass it outside the server socket" is partly what confused me - what you mean is "give the data to a method that is not a dedicated part of the Socket processing code", right?
The simple way to do this is, once you've accumulated a complete "logical message" is to call a method to process it from your asynchronous ReadCallback method. So the business logic is actually running as a subroutine of the Socket code. But this is only OK for trivial processing that does not block for any length of time.
A more common technique is to use multi-threading and cross-thread dispatching techniques. Then the business logic is semi-independent of the Socket code. There are many possible ways of doing this. I've written code that explicitly uses an AutoResetEvent and a queue of messages (with a lock), but it is a bit messy. The modern way (which I've not used personally) is via the C# async and await facility.
Finally, a few comments on the code you present. It is safer to not use an end-of-file token, and instead prefix each logical message with a message length, for example an Int32 encoded/decoded via BitConverter to a 4-byte array (be careful of big endian vs. little endian). The problem with the end-of-file marker is that it is conceivable that the marker could be split between two calls to your ReadCallback method.
Similarly, it is best to first accumulate the entire message as raw bytes, and then decode the whole message back to string. Again, the problem could be that a UTF-8 two-byte sequence could get split across two calls to ReadCallback.
Hope this helps.
EDIT:
Just want to mention that the fact that TCP/IP input is considered to be a stream of bytes does make the processing tricky. I've already indicated that a length prefix is safer than an end-of-file token, and that accumulating the whole message before converting from UTF-8 to string is safer than converting individual segments.
But in addition you have to be careful that you have at least 4 bytes before you try to convert it into the length. It is conceivable that you get one message plus the first 2 bytes of the next one, so you only have half of the length prefix for the second message. Then you have to just save those 2 bytes and wait for the next call before you can even convert the length.
Normally you get a whole message on each call, and it is very rare that this streaming causes problems. And it never happens during testing. But according to Murphy's law eventually it will happen, and at the worst possible time.

Related

Checking if NamedPipeClientStream has something to read

I need to check a NamedPipeClientStream to see if there are bytes for it to read before I attempt to read it. The reason for this is because the thread stops on any read operation if there's nothing to read and I simply cannot have that. I must be able to continue even if there's no bytes to read.
I've also tried wrapping it in a StreamReader, which I've seen suggested, but that has the same result.
StreamReader sr = new StreamReader(myPipe)
string temp;
while((temp = sr.ReadLine()) != null) //Thread stops in ReadLine
{
Console.WriteLine("Received from server: {0}", temp);
}
I either need for the read operations to not wait until there are bytes to read, or a way to check if there are bytes to read before attempting the read operations.
PipeStream does not support the Length, Position or ReadTimout properties or Seek...
This is a very bad pattern. Structure your code so that there's a reading thread that always tries to read until the stream has ended. Then, make your threads communicate to achieve the logic and control flow you want.
It is generally not possible to check whether an arbitrary Stream has data available. I think it's possible with named pipes. But even if you do that you need to ensure that incoming bytes will be read in a timely manner. There is no event for that. Even if you manage all of this the code will be quite nasty. It will not be easy to mentally verify.
For that reason, simply keep a reading loop alive. You could make that reading loop enqueue the data into a queue (maybe BlockingCollection). Then other threads can check that queue for data or wait for data to arrive. The stream will always be drained correctly. You can signal the stream end by enqueueing null.
When I say "thread" I mean any primitive that gives you the appearance of a thread. These days you would never use Thread. Rather, use async/await or Task.

C# timed sempahore to syncronize two threads and a single output buffer

ADDED PREFACE
Here I want better explain the scenario of my application.
I need a windows service to "convert" a SerialPort into a TCPPort. For instance let's say I have a serial ticket printer connected to a COM port for raw ascii stream and I want to access it by TCP sockets from network. The result should be that the serial printer becomes a network printer, my service should link many tcp sockets to com port.
This is the scheme:
The main problem is that the COM port has a unique connection but here I can have many simultaneous connection from network clients. I need to synchronize writes to COMport and get output from the COMport and copy that to all connected TCP clients.
With TCPconnections I cannot know when a write stream is really close, because a network client can send a print job without closing its connection and send another job after a while.
Serial printers are inline printer and there is not a start/end command, it can simply receive ascii chars and they are printer in receiving order.
This is because I need to be sure that network input will not be mixed and I want a timer that can understand that the job is really end before relase the synchronized write lock.
ORIGINAL QUESTION
I have two threads: A, B.
Both threads have to write in a single output buffer by WriteToOutput() method, and I want to be sure that the output will not be mixed if both A and B want to write in the output at the same time.
For first I need a simple semaphore:
private object locker = new object();
public void WriteToOutput(byte[] threadBuffer)
{
lock (locker)
{
//... copy threadBuffer to outputBuffer
}
}
But I need a little more safety to divide the outputs because a thread can empty its buffer but it can be filler right after the lock release.
So in case of concurrency if the thread A gets the lock, I want to wait the second thread B for while, let's say a tick of 1s. If in this time the thread A wants to write something more, it has the priority, and B has to wait another tick. If the thread A do not write for a n entire tick, then it can really relase the lock and the B thread can get the lock.
Just for correction - that's a monitor, not a semaphore.
As for the rest, this sounds like a weird multi-threaded design, and it's going to be brittle and unreliable. Make it obvious when it's safe to release the shared resource - relying on any kind of timing for synchronization is a terrible idea.
The problem is that the WriteToOutput method is obviously not a good point for the synchronization! If you need to ensure multiple writes from the same thread are serialized, you need to move your synchronization point somewhere else. Or, pass a Stream instead of byte[], and read that until it's closed inside the lock - this will effectively do the same thing, move the responsibility to the callee. Just make sure you don't lock it up forever by forgetting to close the stream :) Another alternative would be to use a BlockingCollection<byte[]>. It's hard to tell what's the best option when we don't really know what you're actually trying to do.
EDIT:
Okay, serial port communication is about the only proper use of timing like this I can think of. Of course, it can also be a bit tricky to handle the communication on a non-realtime system.
The best way to solve this would be to have a single endpoint for all your access to the serial port which would handle the communication and synchronization. Instead of calling the method from your other threads, you would just post data that the endpoint would read. However, this requires you to have a way of identifying the other threads - and I'm not sure if you have something like that (perhaps the EndPoint of the TCP socket?). The simplest way would be using the BlockingCollection:
private readonly object _syncObject = new object();
public void SendData(BlockingCollection<byte[]> data)
{
lock (_syncObject)
{
byte[] buffer;
while (data.TryTake(out buffer, TimeSpan.FromSeconds(1)))
{
// Send the data
}
}
}
This will keep reading and sending data from the queue, as long as it can get another buffer in at most second-long periods - if it takes more than a second, the method will exit and another thread will have a chance.
In the socket receive thread, you'd declare the blocking collection - this will vary based on your implementation of the receive code. If you have a single instance of some class for each of the different sockets, you can just declare it as an instance field. If not, you could use ThreadLocal. This assumes you're using manual threads, one per socket - if not, you'll need a different storage.
private readonly BlockingCollection<byte[]> _dataQueue = new BlockingCollection<byte[]>();
private void ReceiveHandler(byte[] data)
{
// This assumes the byte array passed is already a copy
_data.Add(data);
SendData(_dataQueue);
}
This is definitely not the best way to handle this, but it's certainly the simplest I can think of right now - it's barely any code at all, and it only uses lock and BlockingCollection.
I'd take a look at ReaderWriterLockSlim.
https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim(v=vs.110).aspx

What can happen in two concurrent NetworkStream.BeginWrite calls?

I have two methods on my Sender class:
public void SendMessage(OutgoingMessage msg)
{
try
{
stream.BeginWrite(msg.TcpData, 0, 16, messageSentCallback, msg);
}
catch
{
// ...
}
}
private void messageSentCallback(IAsyncResult result)
{
stream.EndWrite(result);
if (result.IsCompleted)
onDataSent(result.AsyncState as OutgoingMessage);
}
Other parts of the program can call (if they have an access to the Sender) the SendMessage() method. Since the program works in multi-threading environment, multiple threads have access to the Sender object.
I have 2 questions:
Q1) Would making two concurrent calls to the SendMessage method be able to mess up the TCP communication (by filling the TCP outgoing buffer with mixed data)?
Q2) Would enclosing the stream.BeginWrite() call into the lock { } solve this problem?
As far as I understand, the call to BeginWrite simply stores the data into the TCP outgoing buffer. Is that right?
Yes, a lock is required to avoid problems. However, I would switch to a different approach, both to solve concurrency problems as well as to make the thread interaction more easy to reason about.
You could have a shared queue where several threads put requests that need to be written to the stream. A single thread then reads requests from the queue and makes write operations. Now it's much easier to understand what is going on and you don't have to worry about synchronizing the writes. You could use one of the concurrent collections like ConcurrentQueue.
MSDN Says
As long as there is one unique thread for the write operations and one
unique thread for the read operations, there will be no
cross-interference between read and write threads and no
synchronization is required.
Which means that if you have more than one threads sending data then you should use lock to make sure only one thread calls BeginWrite at a time in order to send data without any interference
If you would like to minimize blocking and maintain high concurrency with multiple writer threads I would recommend using the Socket.SendAsync which accepts a SocketAsyncEventArgs.
You could preallocate a number of SocketAsyncEventArgs (with its associated buffer space) that are used as writers, in which case, rather than having a lock you would have a SemaphoreSlim which would allow a number of 'simultaneous' writes pushing the synching lower down the protocol stack.
Here is a Code Gallery sample that could get you started (also demonstrates pooling for your buffers.)
Here is a codeproject article that also demonstrates its use.
Good luck!

TcpClient - waiting for data to become available

In my C# application, I have a thread which basically continually reads from a TcpClient until told to stop. I use WaitHandles for this purpose, for example:
private ManualResetEvent stopping;
private void Receive()
{
while (!this.stopping.WaitOne(10))
{
while (this.client.Available > 0)
{
// Read and process data
}
}
}
As you can see, I'm waiting for the thread to be told to stop. If it hasn't been, it reads all data from the TcpClient and loops.
The problem I have is the 10ms delay, which I'd rather not have. I could reduce it, but I'd prefer a solution where the program will pause until EITHER the thread is told to stop, or more data becomes available.
In effect, what I want is a WaitHandle which tells me when data is available on the TcpClient. That way, I can use WaitHandle.WaitAny. Is there any way I can do this, or can someone suggest an alternative approach?
This can't be a bodge as it needs to be a fairly performant -and- lightweight background process.
You'll need to use the BeginRead method on the underlying NetworkStream. This will return a IAsyncResult which has a AsyncWaitHandle property. Now you create an array of WaitHandle's, stick the AsyncWaitHandle in [0], the ManualResetEvent in [1] and then call WaitHandle.WaitAny() with the array, and it will either return the index of the handle that is set, or WaitTimeout on time out.
Once you know it's the AsyncHandle that's set, you can use EndRead to complete the read, and get the data into your buffer.
The help for BeginRead says you need a callback function, but you can pass Null for this and code everything in your base function if you prefer.

How can two threads access a common array of buffers with minimal blocking ? (c#)

I'm working on an image processing application where I have two threads on top of my main thread:
1 - CameraThread that captures images from the webcam and writes them into a buffer
2 - ImageProcessingThread that takes the latest image from that buffer for filtering.
The reason why this is multithreaded is because speed is critical and I need to have CameraThread to keep grabbing pictures and making the latest capture ready to pick up by ImageProcessingThread while it's still processing the previous image.
My problem is about finding a fast and thread-safe way to access that common buffer and I've figured that, ideally, it should be a triple buffer (image[3]) so that if ImageProcessingThread is slow, then CameraThread can keep on writing on the two other images and vice versa.
What sort of locking mechanism would be the most appropriate for this to be thread-safe ?
I looked at the lock statement but it seems like it would make a thread block-waiting for another one to be finished and that would be against the point of triple buffering.
Thanks in advance for any idea or advice.
J.
This could be a textbook example of the Producer-Consumer Pattern.
If you're going to be working in .NET 4, you can use the IProducerConsumerCollection<T> and associated concrete classes to provide your functionality.
If not, have a read of this article for more information on the pattern, and this question for guidance in writing your own thread-safe implementation of a blocking First-In First-Out structure.
Personally I think you might want to look at a different approach for this, rather than writing to a centralized "buffer" that you have to manage access to, could you switch to an approach that uses events. Once the camera thread has "received" an image it could raise an event, that passed the image data off to the process that actually handles the image processing.
An alternative would be to use a Queue, which the queue is a FIFO (First in First Out) data structure, now it is not thread-safe for access so you would have to lock it, but your locking time would be very minimal to put the item in the queue. There are also other Queue classes out there that are thread-safe that you could use.
Using your approach there are a number of issues that you would have to contend with. Blocking as you are accessing the array, limitations as to what happens after you run out of available array slots, blocking, etc..
Given the amount of precessing needed for a picture, I don't think that a simple locking scheme would be your bottleneck. Measure before you start wasting time on the wrong problem.
Be very careful with 'lock-free' solutions, they are always more complicated than they look.
And you need a Queue, not an array.
If you can use dotNET4 I would use the ConcurrentQuue.
You will have to run some performance metrics, but take a look at lock free queues.
See this question and its associated answers, for example.
In your particular application, though, you processor is only really interested in the most recent image. In effect this means you only really want to maintain a queue of two items (the new item and the previous item) so that there is no contention between reading and writing. You could, for example, have your producer remove old entries from the queue once a new one is written.
Edit: having said all this, I think there is a lot of merit in what is said in Mitchel Sellers's answer.
I would look at using a ReaderWriterLockSlim which allows fast read and upgradable locks for writes.
This isn't a direct answer to your question, but it may be better to rethink your concurrency model. Locks are a terrible way to syncronize anything -- too low level, error prone, etc. Try to rethink your problem in terms of message passing concurrency:
The idea here is that each thread is its own tightly contained message loop, and each thread has a "mailbox" for sending and receiving messages -- we're going to use the term MailboxThread to distinguish these types of objects from plain jane threads.
So instead of having two threads accessing the same buffer, you instead have two MailboxThreads sending and receiving messages between one another (pseudocode):
let filter =
while true
let image = getNextMsg() // blocks until the next message is recieved
process image
let camera(filterMailbox) =
while true
let image = takePicture()
filterMailbox.SendMsg(image) // sends a message asyncronous
let filterMailbox = Mailbox.Start(filter)
let cameraMailbox = Mailbox.Start(camera(filterMailbox))
Now you're processing threads don't know or care about any buffers at all. They just wait for messages and process them whenever they're available. If you send to many message for the filterMailbox to handle, those messages get enqueued to be processed later.
The hard part here is actually implementing your MailboxThread object. Although it requires some creativity to get right, its wholly possible to implement these types of objects so that they only hold a thread open while processing a message, and release the executing thread back to the thread-pool when there are no messages left to handle (this implementation allows you to terminate your application without dangling threads).
The advantage here is how threads send and receive messages without worrying about locking or syncronization. Behind the scenes, you need to lock your message queue between enqueing or dequeuing a message, but that implementation detail is completely transparent to your client-side code.
Just an Idea.
Since we're talking about only two threads, we can make some assumptions.
Lets use your tripple buffer idea. Assuming there is only 1 writer and 1 reader thread, we can toss a "flag" back-and-forth in the form of an integer. Both threads will continuously spin but update their buffers.
WARNING: This will only work for 1 reader thread
Pseudo Code
Shared Variables:
int Status = 0; //0 = ready to write; 1 = ready to read
Buffer1 = New bytes[]
Buffer2 = New bytes[]
Buffer3 = New bytes[]
BufferTmp = null
thread1
{
while(true)
{
WriteData(Buffer1);
if (Status == 0)
{
BufferTmp = Buffer1;
Buffer1 = Buffer2;
Buffer2 = BufferTmp;
Status = 1;
}
}
}
thread2
{
while(true)
{
ReadData(Buffer3);
if (Status == 1)
{
BufferTmp = Buffer1;
Buffer2 = Buffer3;
Buffer3 = BufferTmp;
Status = 0;
}
}
}
just remember, you're writedata method wouldn't create new byte objects, but update the current one. Creating new objects is expensive.
Also, you may want a thread.sleep(1) in an ELSE statement to accompany the IF statements, otherwise one a single core CPU, a spinning thread will increase the latency before the other thread gets scheduled. eg. The write thread may run spin 2-3 times before the read thread gets scheduled, because the schedulers sees the write thread doing "work"

Categories

Resources