A few words about an ongoing design and implementation
I send a lot of requests to the remote application (running on a different
host, of course), and the application send back data.
About client
Client is a UI that spawn a separate thread to submit and process the requests. Once it submits all the requests, it calls Wait. And the Wait will parse all events coming the app and invoke client's callbacks.
Below is the implementation of Wait.
public void Wait (uint milliseconds)
{
while(_socket.IsConnected)
{
if (_socket.Poll(milliseconds, SelectMode.SelectRead))
{
// read info of the buffer and calls registered callbacks for the client
if(_socket.IsAvailable > 0)
ProcessSocket(socket);
}
else
return; //returns after Poll has expired
}
}
The Wait is called from a separate thread, responsible for managing network connection: both inbound and outbound traffic:
_Receiver = new Thread(DoWork);
_Receiver.IsBackground = true;
_Receiver.Start(this);
This thread is created from UI component of the application.
The issue:
client sometimes sees delays in callbacks even though main application has sent the data on time. Notably, one the message in Poll was delayed until I client disconnected, and internally I called:
_socket.Shutdown(SocketShutdown.Both);
I think something funky is happening in the Poll
Any suggestions on how to fix the issue or an alternative workaround?
Thanks
please let me know if anything is unclear
A couple of things. First, in your example, is there a difference between "_socket" and "socket"? Second, you are using the System.Net.Sockets.Socket class, right? I don't see IsConnected or IsAvailable properties on that class in the MSDN documentation for any .NET version going back to 1.1. I assume these are both typing mistakes, right?
Have you tried putting an "else" clause on the "IsAvailable > 0" test and writing a message to the Console/Output window, e.g.,
if (_socket.IsAvailable > 0) {
ProcessSocket(socket);
} else {
Console.WriteLine("Poll() returned true but there is no data");
}
This might give you an idea of what might be going on in the larger context of your program.
Aside from that, I'm not a big fan of polling sockets for data. As an alternative, is there a reason not to use the asynchronous Begin/EndReceive functions on the socket? I think it'd be straightforward to convert to the asynchronous model given the fact that you're already using a separate thread to send and receive your data. Here is an example from MSDN. Additionally, I've added the typical implementation that I use of this mechanism to this SO post.
What thread is calling the Wait() method? If you're just throwing it into the UI threadpool, that may be why you experience delays sometimes. If this is your problem, then either use the system threadpool, create a new one just for the networking parts of your application, or spawn a dedicated thread for it.
Beyond this, it's hard to help you much without seeing more code.
Related
Here is my problem, I got a WCF project, which doesnt really matter in fact because it's more about C#/.NET I believe. In my WCF Service when client is requestinq one of the methods I make the validation of the input, and if it succeeds I start some business logic calculactions. I want to start this logic in another thread/task so after the input validation I can immediately return response. Its something like this:
XXXX MyMethod(MyArgument arg)
{
var validation = _validator.Validate(arg);
if (validation.Succeed)
{
Task.Run(() => businessLogic())
}
return MyResponseModel();
}
I need to make it like this because my buesinessLogic can take long time calculactions and database saves in the end, but client requesting the Service have to know immediately if the model is correct.
In my businessLogic calculactions/saves that will be running in background thread I have to catch exceptions if something fail and save it in database. (its pretty big logic so many exceptions can be thrown, like for example after calculactions im persisting the object in the database so save error can be thrown if database is offline for example)
How to correctly implement/what to use for such a requirements? I am just giving consideration if using Task.Run and invoking all the logic in the action event is a good practice?
You can do it like this.
Be aware, though, that worker processes can exit at any time. In that case outstanding work will simply be lost. Maybe you should queue the work to a message queue instead.
Also, if the task "crashes" you will not be notified in any way. Implement your own error logging.
Also, there is no limit to the number of tasks that you can spawn like this. If processing is too slow more and more work will queue up. This might not at all be a problem if you know that the server will not be overloaded.
It was suggested that Task.Run will use threads and therefore not scale. This is not necessarily so. Usually, the bottleneck of any processing is not the number of threads but the backend resources being used (database, disk, services, ...). Even using hundreds of threads is not in any way likely to be a bottleneck. Async IO is not a way around backend resource constraints.
We are just starting to use RabbitMQ with C#. My current plan is to configure in the database the number and kind of consumers to run on a given server. We have an existing windows service and when that starts I want to spawn all of the RabbitMQ consumers. My question is what is the best way to spwan these from a windows service?
My current plan is to read the configuration out of the database and spawn a long running task for each consumer.
var t = new Task(() =>
{
var instance = LoadConsumerClass(consumerEnum, consumerName);
instance.StartConsuming();//blocking call
}, TaskCreationOptions.LongRunning);
t.Start();
Is this better or worse than creating a thread for each consumer?
var messageConsumer = LoadConsumerClass(consumerEnum, consumerName);
var thread = new Thread(messageConsumer.StartConsuming);
I'm hoping that more than a few others have already tried what I'm doing and can provide me with some ideas for what worked well and what didn't.
In EasyNetQ we have a single dispatcher thread for all consumers on a single connection. We also provide a facility to to return a Task from the message handler, so it's easy to do async IO if you want to make a database call, go to the file system, or make a web service request.
Having said that it's perfectly legitimate to have each consumer consuming on a different thread. I guess it depends on your message throughput, how many consumers you have and the nature of your message handlers.
I'd stick with Tasks as they give you more features and generally allow for less boilerplate code.
And, If I understand your code correctly, you'd be sharing a channel (IModel) in second case. This might cause troubles as the default IModel implementation is not thread safe (or used to be). There're more subtle nuances regarding thread safety you'd have to watch out.
But it depends on your usage patterns. If you don't expect many messages/sec on each consumer, or if your app can handle messages fast then perhaps a single thread for all consumers will be you best option.
Task is great, but you not really going to use all the stuff it can do. The only thing you need is to do work in parallel.
I faced the same question couple of months ago, what I finished with - is a thread per computation type (per queue) which is blocking on message arrival and doesn't consume cpu when waiting for messages.
Open a new channel for each one of the threads.
As for connections - if you application is meant to deal with high load of messages, I suggest you opening connection for every X workers (figure you your X), since only one channel can send the messages through the connection, so assuming one worker is consuming large message the others are blocked on connection level waiting it to be free.
I thought C# was an event-driven programming language.
This type of thing seems rather messy and inefficient to me:
tcpListener.Start();
while (true)
{
TcpClient client = this.tcpListener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication));
clientThread.Start(client);
}
I also have to do the same kind of thing when waiting for new messages to arrive. Obviously these functions are enclosed within a thread.
Is there not a better way to do this that doesn't involve infinite loops and wasted CPU cycles? Events? Notifications? Something? If not, is it bad practice to do a Thread.Sleep so it isn't processing as nearly as often?
There is absolutely nothing wrong with the method you posted. There are also no wasted CPU cycles like you mentioned. TcpClient.AcceptTcpClient() blocks the thread until a client connects to it, which means it does not take up any CPU cycles. So the only time the loop actually loops is when a client connects.
Of course you may want to use something other than while(true) if you want a way to exit the loop and stop listening for connections, but that's another topic. In short, this is a good way to accept connections and I don't see any purpose of having a Thread.Sleep anywhere in here.
There are actually three ways to handle IO operations for sockets. The first one is to use the blocking functions just as you do. They are usually used to handle a client socket since the client expects and answer directly most of the time (and therefore can use blocking reads)
For any other socket handlers I would recommend to use one of the two asynchronous (non-blocking) models.
The first model is the easiest one to use. And it's recognized by the Begin/End method names and the IAsyncResult return value from the Begin method. You pass a callback (function pointer) to the Begin method which will be invoked when something has happened. As an example take a look at BeginReceive.
The second asynchronous model is more like the windows IO model (IO Completion Ports) . It's also the newest model in .NET and should give you the best performance. As SocketAsyncEventArgs object is used to control the behavior (like which method to invoke when an operation completes). You also need to be aware of that an operation can be completed directly and that the callback method will not be invoked then. Read more about RecieveAsync.
I would like to rephrase my previous question How to create Singleton with async method?
Imagine messaging application (like icq) - something that should be always connected to server and can post messages.
I need to implment class Connection. It should be singleton, because it contains "socket" inside and that socket should persist during entirely application lifetime.
Then I want to implement async method Connection.postMessage
Because postMessage can take significant ammount of time:
postMessage should be async
postMessage should queue messages if neccesary
Note my application posts dozens messages per second, so it is not appropiate to create new Thread for each postMessage call.
I diffenetely need to create exactly one extra thread for messages posting but I don't know where and how.
upd: good example http://msdn.microsoft.com/en-us/library/yy12yx1f(v=vs.80).aspx
No, Postmessage (itself) should not be async .
It should
be Thread-safe
ensure the Processing thread is running
queue the message (ConcurrentQueue)
return
And the Processing Thread should
Wait on the Queue
Process the messages
maybe Terminate itself when idle for xx milliseconds
What you have is a classic Producer/Consumer situation with 1 Consumer and multiple Producers.
PostMessage is the entry-point for all producers.
jp,
You're looking at a classic producer/consumer problem here... During initialisation the Connection should create a MessageQueue start a Sender in it's own background thread.
Then the connection posts just messages to the queue, for the Sender to pickup and forward when ready.
The tricky bit is managing the maximum queue size... If the producer consistently outruns the consumer then queue can grow to an unmanagable size. The simplest approach is to block the producer thread until the queue is no longer full. This can be done with a back-off-ARQ. ie: while(queue.isFull) sleep(100, "milliseconds"); queue.add(message); If you don't require 100% transmission (like a chat-app, for instance) then you can simply throw a MessageQueueFullException, and the poor client will just have to get over it... just allways allow them to resubmit later... allowing the user manage the retrys for you.
That's how I'd tackle it anyway. I'll be interested to see what others suggestions are muted.
Hope things work out for you. Cheers. Keith.
SO users,
I have 3 threads running simultaneously at any given time, trouble is after thread 1 tries to connect to a server by passing a username to it thread 2 is being invoked and by the time its thread 1's turn the server closes its connection on the code.
Is there anywhere I can implement sending username and password simultaneously with out threads interrupting each other at this time?
Thx!,
Nidhi
I very much doubt that it's genuinely thread contention which is the problem here.
Threads timeslice very quickly, and the server would have to have a ridiculously short timeout for your diagnosis to be correct.
My guess is there's something different wrong with your code, but we can't really tell what it is without seeing some code.
threads typically swap on the order of milliseconds, so i don't think thats whats causing your program to disconnect.
That said, you can implement locks/mutexes to ensure that critical code is executed without other threads executing their code, and even use thread prioritization to ensure one thread gets priority over others - but you cannot force a thread not to yield, the operating system can decide you've run long enough and force you to yield regardless. Besides, the behavior your looking for is more or less explicitly prevented in all modern schedules to prevent starvation of other processes.
It looks like you're trying to multiplex multiple data streams on one socket. So you may be running into a thread switching problem while waiting for the server, but if that's the case you're probably doing something like this, which is an inappropriate way to multithread.
void Task(int type)
{
// Authenticate
// Send Data
// Disconnect
}
// Connect
Thread.Start(Task(1));
Thread.Start(Task(2));
Thread.Start(Task(3));
If you've got threads 1, 2, and 3 doing work on the server in tandem you've got a few ways to do it:
1.) Do your work threaded with different connections
void Task(int type)
{
// Connect
// Authenticate
// Send Data
// Disconnect
}
Thread.Start(Task(1));
Thread.Start(Task(2));
Thread.Start(Task(3));
2.) Do your work singlethreaded with one connection
void Task(int type)
{
// Send Data
}
// Connect
// Authenticate
Task(1);
Task(2);
Task(3);
// Disconnect
3.) Use multiple connections