My application is a communications server that receives TCP messages from a web server and then re-broadcasts the message to a number of iPads. It's a windows forms application in C#. Program.cs creates an instance of the primary form and then that form creates four threads that do the communications work. There is a thread that listens for messages from the web server, a thread that processes the incoming messages into the data that needs to be transmitted and a thread that handles sending the outbound messages. The fourth thread does database cleanup and spends 99% of it's time sleeping.
The problem I'm seeing is the GUI locks up with a load is placed on the system. On incoming message may represent 50 or 100 outgoing messages. While testing I'm restricting they system to only send 5 messages out at a time, so it requires a longer transmission time. The sending process is using async call backs, but even it it wasn't, I can't understand why load on the tread could be stalling the GUI thread.
I'm removed a much of the cross thread communications from the thread to the GUI for status update. The pattern for communications to the GUI is:
public void StatusOutput(string myString)
{
if (this.lbStatus.InvokeRequired)
{
this.lbStatus.BeginInvoke(new DebugOutputInvoker(StatusOutput), myString);
}
else
{
lbStatus.Items.Add(myString);
while (lbStatus.Items.Count >= 501)
{
lbStatus.Items.RemoveAt(0);
}
lbStatus.SelectedItem = lbStatus.Items.Count - 1;
} // StatusUpdate() ...
Can anyone give me any advice on how to pursue this? I though threads were completely isolated from the GUI and couldn't load it.
Thanks!
As an update, I removed all thread to GUI communications and the GUI stopped locking up. So this proved it wasn't a GUI thread issue. I work through the threads till I found out it's the TCPSender thread that has a lot of async callback functions, potentially hundreds of them. When ever this thread get's busy with it's async calls, the GUI locks up. I suspect it has to do with call backs happening while the thread has one of the GUI's methods in process.
I've solved the issue with making a new thread that just collects data from the operational threads and then updates the user interface. General status message that were transferred to the status display on the GUI thread are now queued and updated to the GUI through this new thread.
The GUI remains responsive and actually seems to be able to display more data now.
Related
In another SO question, I was advised to send an asynchronous network request, rather than sending a synchronous request on a background thread. The reason was so that I don't waste a thread. I'm trying to understand how this is so.
This is the original approach. I can understand how there are two threads here. One is the main thread (1), and one is the background thread (Task.Run) (2) that makes the WCF call:
This is my sketch of the suggested approach. I'm trying to understand how a thread is saved. After the async WCF call, won't another thread be created for the callback from the async WCF call?
After thinking about this further, perhaps only one thread is used if callback processing isn't necessary?
In your WPF client you likely have a OnClick somewhere in your client, where is the thread that is checking if the client was clicked or not?
The answer to that the OS itself is checking for the click then passing the message along to to the message pump which in turn invokes your function. The callback for the WCF function is like that, the OS itself is listening for the reply message and when it gets one it will send a signal that will find a free thread on the thread pool and execute the callback at that time.
The major difference between synchronously holding the thread and letting the callback method generate a thread at the end is the fact that the thread pool is a pool. When a thread in the thread pool finishes its work it does not get destroyed, it waits around a while to see if more work is available to be done and it will be reused to do that new work.
So the two choices are
Have 1 Thread sit there waiting doing no other work waiting for the function to unblock (Sync + thread)
Reuse an existing thread that has finished it's work already (or spawn a new one if none are waiting and we are below ThreadPool.GetMaxThreads()) when the OS tells us the information we where waiting for has shown up, give it the short task of handling the callback, then letting the thread go back in to the pool to do other work for other callbacks as they come in.
I have a program that retrieves data from a serial device, and then puts it in a server that is accessible by certain programs that can handle this protocol. This server is a third party program that is in the form of an active x control.
The hardware devices require a Thread.Sleep, which is unfortunate. The programs that monitor the server sometimes query the server during the time when a thread is sleeping. This causes it to think the server has failed.
My next idea was to put the server on a separate thread, one solely dedicated for the server tasks. In the UI thread, I run the following code:
Thread workerThread = new Thread(DoServerWork);
workerThread.SetApartmentState(ApartmentState.STA);
workerThread.Start();
In the delegate, I have
public void DoServerWork()
{
rtu = new AxASMBSLVLib.AxASMBSLV();
rtu.CreateControl();
rtu.BeginInit();
rtu.OpenPort();
while (true)
{
}
}
The problem is that the server starts to work, and then becomes unresponsive in about 5 seconds. My initial thought is that the thread is exiting, but the while(true) should prevent that from happening. Any thoughts?
Since you are running this in a Single Threaded Apartment (STA), once that thread hits the empty endless loop, nothing more can happen. An endless loop is generally not a good idea. You should probably use a timer to periodically perform the server work in its OnElapsed event handler.
It is a modbus TCP/IP slave from a third party company. The first option is to "drag and drop" it from the toolbox to the GUI, causing it to be on the UI thread.
Since ActiveX requires STA : exactly the right thing.
I must call Thread.Sleep on the UI thread,
that should never be necessary, here lies your real problem. Never block/sleep he main thread.
Your question should be about how to avoid the Sleep().
I've run into a problem while writing an async multi-server network app in c#. I have many jobs being taken care of by the thread pool and these include the writes to the network sockets. This ended up allowing for the case where more than one thread could write to the socket at the same time and discombobulate my outgoing messages. My idea for getting around this was to implement a queue system where whenever data got added to the queue, the socket would write it.
My problem is, I can't quite wrap my head around the architecture of something of this nature. I imagine having a queue object that fires an event on whenever data gets added to the queue. The event then writes the data being held in the queue, but that won't work because if two threads come by and add to the queue simultaneously, even if the queue is made to be thread safe, events will still be fired for both and I'll run into the same problem. So then maybe someway to hold off an event if another is in progress, but then how do I continue that event once the first finishes without simply blocking the thread on some mutex or something. This wouldn't be so hard if I wasn't trying to stay strict with my "block nothing" architecture but this particular application requires that I allow the thread pool threads to keep doing their thing.
Any ideas?
While similar to Porges answer it differs a bit in implementation.
First, I usually don't queue the bytes to send, but objects and seralize them in the sending thread but I guess that's a matter of taste.
But the bigger difference is in the use of ConcurrentQueues (in addition to the BlockingCollection).
So I'd end up with code similar to
BlockingCollection<Packet> sendQueue = new BlockingCollection<Packet>(new ConcurrentQueue<Packet>());
while (true)
{
var packet = sendQueue.Take(); //this blocks if there are no items in the queue.
SendPacket(packet); //Send your packet here.
}
The key-take away here is that you have one thread which loops this code, and all other threads can add to the queue in a thread-safe way (both, BlockingCollection and ConcurrentQueue are thread-safe)
have a look at Processing a queue of items asynchronously in C# where I answered a similar question.
Sounds like you need one thread writing to the socket synchronously and a bunch of threads writing to a queue for that thread to process.
You can use a blocking collection (BlockingCollection<T>) to do the hard work:
// somewhere there is a queue:
BlockingCollection<byte[]> queue = new BlockingCollection<byte[]>();
// in socket-writing thread, read from the queue and send the messages:
foreach (byte[] message in queue.GetConsumingEnumerable())
{
// just an example... obviously you'd need error handling and stuff here
socket.Send(message);
}
// in the other threads, just enqueue messages to be sent:
queue.Add(someMessage);
The BlockingCollection will handle all synchronization. You can also enforce a maximum queue length and other fun things.
I don't know C#, but what I would do is have the event trigger the socket manager to start pulling from the queue and write things out one at a time. If it is already going the trigger won't do anything, and once there is nothing in the queue, it stops.
This solves the problem of two threads writing to the queue simultaneously because the second event would be a no-op.
You could have a thread-safe queue that all your worker thread write their results to. Then have another thread that polls the queue and sends results when it sees them waiting.
I have a C# HttpListener that runs on a single thread and parses data sent to it by another program. My main problem is not all the data sent to the server is received. I only assume this is due to the limitations of it being run on a single thread. I have searched high and low for a simple multi-threading solution so it may receive al the data sent to it, and came up empty handed. Any help in transforming this into a multi-threaded application would be much appreciated.
private void frmMain_Load(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(ThreadProc));
t.Start();
}
public static void ThreadProc()
{
while (true)
{
WebBot.SimpleListenerExample(new string[] { "http://localhost:13274/" });
//Thread t = new Thread(new ThreadStart(ThreadProc));
//t.Start();
Application.DoEvents();
}
}
First thing first: verify that your hypothesis is indeed correct. You need to check:
How much data is sent
How much data is received
How long does it take to send the data
How long does it take to operate on the data
HTTP works over TCP, which generally guarantees delivery, so even if it will take a long time, your server should be getting all the incoming information.
That said, if you still want to make the process multi-threaded, I would recommend the following design:
One thread like you have right now (LISTENER THREAD), that accepts incoming data.
Another set of threads that will process the incoming data (WORKER THREADS).
The listener thread will only receive the data and place it in a queue.
The worker threads will dequeue the queue and operate on the data.
Several notes and things to think about, though:
Take care of thread synchronization - specifically, you need to protect the queue.
Think if it matters which worker thread will get the data. If there are several chunks that need to be taken care of a specific worker thread, you'll need to address this problem.
In some cases, if there is a very high load on the listener thread, the queue may become a bottleneck, or more precisely - the locking on the queue may become a bottleneck. In this case I would recommend moving into a model of N queues for N worker threads, and have the listener just pick one in a round-robin fashion. This will minimize the locks and actually since you'll have one reader and one writer you can even get away without a lock (but this is out of scope for that answer).
Yet another option would be to use a thread pool. A thread pool is a pool of threads that are hibernating until they are needed. When the listener gets an incoming input it will allocate it to a free thread, or will enlarge the pool if needed; this way you don't have a queue, and your threads are optimally used.
Simplest Embedded Web Server Ever with HttpListener may help you get started.
I'm creating a server-type application at the moment which will do the usual listening for connections from external clients and, when they connect, handle requests, etc.
At the moment, my implementation creates a pair of threads every time a client connects. One thread simply reads requests from the socket and adds them to a queue, and the second reads the requests from the queue and processes them.
I'm basically looking for opinions on whether or not you think having all of these threads is overkill, and importantly whether this approach is going to cause me problems.
It is important to note that most of the time these threads will be idle - I use wait handles (ManualResetEvent) in both threads. The Reader thread waits until a message is available and if so, reads it and dumps it in a queue for the Process thread. The Process thread waits until the reader signals that a message is in the queue (again, using a wait handle). Unless a particular client is really hammering the server, these threads will be sat waiting. Is this costly?
I'm done a bit of testing - had 1,000 clients connected continually nagging - the server (so, 2,000+ threads) and it seemed to cope quite well.
I think your implementation is flawed. This kind of design doesn't scale because creating threads is expensive and there is a limit on how many threads can be created.
That is the reason that most implementations of this type use a thread pool. That makes it easy to put a cap on the maximum amount of threads while easily managing new connections and reusing the threads when the work is finished.
If all you are doing with your thread is putting items in a queue, then use the
ThreadPool.QueueUserWorkItem method to use the default .NET thread pool.
You haven't given enough information in your question to specify for definite but perhaps you now only need one other thread, constantly running clearing down the queue, you can use a wait handle to signal when something has been added.
Just make sure to synchronise access to your queue or things will go horribly wrong.
I advice to use following patter. First you need thread pool - build in or custom. Have a thread that checks is there something available to read, if yes it picks Reader thread. Then reading thread puts into queue and then thread from pool of processing threads will pick it. it will minimize number of threads and minimize time spend in waiting state