Im making a server for a new game proyect and im using C# (.NET Framework v4.5) for both client and server.
Im currently using something like this to manage my players.
new Thread(() =>
{
connection.ListenAndSend();
}).Start();
public void ListenAndSend()
{
while(working)
{
if(someThingToRead)
{
//Listening logic here
//Here i call my event for dataReceived with the data i just read.
}
else if (queue.Count > 0)
{
Send(queue.Dequeue().Data); //Send data from the Queue
}
}
The use of a Queue is because i should not access the stream from different threads (it throws InvalidOperationException i think) so i implemented the queue to send data from the same thread.
I think this is mostly OK but im worried about the events.
The events are firing and working fine but i have not tested yet with multiple clients so...
Is the event being executed in the same thread that the listener thread?
Could i have problems with fields being modified by multiple threads at the same time? (Im more experienced in java for example and i remember something about Syncronize interface?)
Its not done right now but later its possible that some event will end up calling the send method so adding data to the send Queue (But this should not be an issue right?)
This game will never be for a large number of players (probably between 2 and 8) if that matters.
Is there some serious problem im not seeing?
As im using the Queue im thinking it does not matter what thread do add the data but will my listening be stopped while it is doing the event code? (If its really on the same thread) and while that could not really be an issue will it be simultaneously accesing fields from multiple threads?
UPDATE:
Can i make all of this just with async/await?? i cant see how to make the listen loop that way but if its really possible please expand in an answer.
Also, this answer says the opposite.
UPDATE 2:
Now that i have tested my code and i know its working fine.
As pointed out in comments i could have done this using async/await with a lot less threads, but:
In which it would be better to use async/await instead of threads, keep in mind my game server should be able to take as much cpu/memory as needed and its fine if it does (Of course the threads are calling sleep when not doing job). And i would like my server to run the closer to real time as possible.
I also would like to point, the first time i made it to start processing my logic the serializing of the game map (around 60k objects) took around 600ms (and that will be for each client) so i ended up moving the serialize job to the socket thread.
With this in mind, who thinks it would be better to use Async/Await instead of new Threads
PD: Im only talking about my server, the game client is indeed using async/await to communicate with the server.
You have 2 options , ether lock the variable (which is not recommended)
How to lock a variable used in multiple threads
or use dispatcher for calling a method from another thread Using the C# Dispatcher
if you are not using WPF, you might take a look to this link : how do I convert wpf dispatcher to winforms
Related
I have noticed that when the new thread is started from serialport Data received event that if the plan of execution includes just a few methods that may change some value and send on another port then it works fine, but if the method needs to do more extensive processing like sending on another port and waiting for ACK, send again and receiving decent sized amounts of data (20KB) in 256 byte packets then the thread just stops somewhere and never completes. When the code is stepped through it seems to work fine. I have read other topics of people asking about this issue but there was no "solution" just to use another method like timers to poll the ports instead. I even made a workaround by having the main thread "poll" a variable that is changed from the event rather then having the event do the work and this seems to work, but when using a windows form I had to create a new thread which seems to be doing the same thing and either not completing the code or not executing the new thread which is just a while look that runs forever checking a variable. I can provide code if needed just wanted some insight on how to address this properly.
Nobody here knew the answer to the questions or explained limitations, but i was able to get around the issues using timers to run while loops checking for variable changes and starting threads that did the same.
I'm investigating about mobile apps using Mono on Visual Studio.Net.
Currently we have an application we want to translate to Android from Windows CE. The original program used small BackgroundWorkers to keep the UI responsive and to keep it updated with the ProgressChanged event. However I have been reading that in Android there are Services that can replace that functionality.
Reading pros and cons about services I know that they are usually used because they have a better priority than threads and, mainly, if the functionality will be used in more than one app.
More info I have found comparing threads and Services say that Services are better used for multiple tasks (like downloading multiple files) and threads for individual tasks (like uploading a single file). I consider this info because BackgroundWorker uses threads.
Is there something I am missing? Basically a service should be for longer tasks because the O.S. gives it better priority (there are less risk it will be killed) and Threads/BackgroundWorkers are better for short tasks. Are there any more pros/cons to use one or the other?
Thank you in advance!
[Edit]
If you need a very specific question... how about telling me when and why would you use a Service instead of a BackgroundWorker? That would be useful.
Some of the functionality I have to recreate on Android:
- GPS positioning and compass information - this has to be working most of the time to get the location of the device when certain events are working and trace in a map its movements.
- A very long process that might even be active for an hour.
The last one is the one I am concerned about. It must be very reliable and responsible, keeping the user informed of what it is doing but also being able to keep working even if the user moves to other activity or functionality (doing a call, hitting the home button, etc.)
Other than that I believe the other functionality that used BackgroundWorker on WinCE will not have problems with Android.
[Edit 2: 20140225]
However I would like to know if the AsyncTask can help me in the next scenario:
- The app reads and writes information from/to another device. The commands are short in nature and the answer is fast so for individual commands there is no problem. However there is a process that can take even an hour or so and during that time it will be asking the status from the device. How would you do it?
I think you're misunderstanding what a Service in Android is. See the documentation on Services:
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application.
Also note:
A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise).
Using a worker thread and using a Service are not mutually exclusive.
If you are looking to move work off the main thread, then clearly you need to use another thread. Through a BackgroundWorker or perhaps the TPL will do just fine in many cases but if you want to interact with UI (e.g. on completion of the task or to update progress in the UI), the Android way is to use an AsyncTask (mono docs).
If this work needs to continue outside of the user interaction with your application, then you may want to host this work (including the BackgroundWorker/Thread/AsyncTask/etc.) in a Service. If the work you want to do is only ever relevant while the user is interacting with your application directly, then a Service is not necessary.
Basically, a service is used when something needs run at the same time as the main app - for example keeping a position updated on a map. A thread is used when consuming a webservice or a long running database call.
The rule-of-thumb, as far as I can see, is rather use threads and close them, unless there is something that needs to happen in the background (like navigation updates). This will keep the footprint of the app smaller, which is a large consideration.
I hope this helps at least a little.
Now that you know you don't need a Service, I want to point out how is the Xamarin guideline doing/recommending this: create a separate thread using ThreadPool and when you want to make changes to GUI from that thread, you call the main thread to do them using the RunOnUiThread method.
I'm not sure that by using AsyncTask you can write your code inline in c#, but with Xamarin recommendation you certainly can, like so:
//do stuff in background thread
ThreadPool.QueueUserWorkItem ((object state) => {
//do some slow operation
//call main thread to update gui
RunOnUiThread(()=>{
//code to update gui here
});
//do some more slow stuff if you want then update gui again
});
http://developer.xamarin.com/guides/android/advanced_topics/writing_responsive_applications/
I have read dozens of articles about threading in c# and Application.DoEvents() ... Still can't use it properly to get my task done:
I have a controller connected to my COM, this controller works on command (i send command, need to wait few ms to get response from it), assume the response is a data that i want to plot every time interval using a loop:
start my loop.
send command to controller via serialPort.
wait for response (wait let say 20 ms).
obtain data.
repeat this loop every let say 100 ms.
this simply doesn't want to work!! i tried to communicate with the data controller on other thread but it seems that it can't access the serialPort which belongs to the main thread (roughly speaking).
any help is appreciated
Application.DoEvents is for all it does - nothing more than a nested call to a windows (low level) message loop on the same thread. Which might easily cause recursion if you call it in in an event handler. You might consider creating your serial port object on the worker thread and communicate through threading classes (i.e. the WaitHandles and similar). Or call back to your UI thread using "BeginInvoke" and "EndInvoke" on the UI object.
If you catch the SerialPort.DataReceived event and then use wither SerialPort.ReadLine or SerialPort.Read(byte[],int,int) those methods will be executed on a new thread. I prefer to use a mutex to control access to the buffer of bytes as a shared resource. Also have you ever communicated with your device successfully? If not in addition to the port setting check the SerialPort.NewLine property and the SerialPort.Handshake property. These settings vary depending on the device you are trying to communicate with.
Why do you use it to begin with?
Have a look at this pages, it might give you a direction
My favorite: Is DoEvents Evil?
From msdn blog Keeping your UI Responsive and the Dangers of Application.DoEvents
From msdn forums Application does not return from call to DoEvents
Without code, it'll be hard to help. Even with code, it might be hard to help :)
I'm agreeing with gunr2171 on this :)
I'm writing a class which would handle all the serial communications with a external device (i.e. reading and writing). The data is being streamed to the computer at 20Hz, and occasionally data is also written to the device. The class would then output valid data through an event to the main UI.
I want to put this class in a separate thread because my previous code caused some 'stuttering' in the device since it was in the main UI thread.
I'm just unsure of how to structure and implement the SerialPort class with a thread/background worker because I'm inexperienced in this area.
Would only the data received event exist inside the thread/background worker?
How would you pass data in and out of the created thread/background worker?
Any hints or suggestions would be much appreciated!
My first tip is that you should think of it like it was network (Socket) communication. The threading issues are much the same. Looking thru the MSDN documentation they have (if I remember correctly) two different ways of doing this, async and sync. I personally would use one of the async ways.
You can also take a look at the new Task library.
Start looking in to that and come back if you have further questions =)
Also from the msdn library serial port with threading example this is to console, but anyway.
You just implement in another thread the actual use of the SerialPort. When the time comes to "notify" your UI, you use "BeginInvoke" to get the actual UI handling to run inside the UI thread.
Something like:
string s = _port.ReadLine();
form.BeginInvoke((MethodInvoker)delegate
{
_textbox.Text = s;
});
Just use the DataReceived event.
I am trying to make an app that will pass data between two servers Connection1 and Conenction2 using sockets.What i would like to do is receive data from Connection1 and pass it to Connection2 and vice-versa.Connection1 and Conenction2 are on different threads. What is the best way to call methods on different threads in order to pass data back and forth between them.Both threads will use the same message object type to communicate in both directions between them.
Thanks
You should use immutable data transfer objects.
As long as a simple object is deeply immutable (meaning that neither it nor any of it's properties can change), there is nothing wrong with using it on multiple threads.
To pass the instances between threads, you might want to use a pseudo-mutable thread-safe stack. (This depends on your design)
If .NET 4 is an option, I'd strongly recommend having a look at the ConcurrentQueue<T> and possibly even wrapping it with a BlockingCollection<T> if that suits your needs.
That depends on what those threads are doing. While passing data between threads is relatively straight forward, waking the threads to process the data can be more tricky. When you design communication with a thread per/connection paradigm, your thread is almost all the time stuck in a Read method, like Socket.Receive. While in this state, other threads cannot actually wake this thread to have him send the data they want it sent. One solution is to have the Receive time out every second and check if it has data to transmit, but that just plain sucks.
Another idea is to have 2 threads per socket, one to Send one to Receive. But then all the advantages of having a thread per socket are gone: you are no longer able to have a simple state management of the 'session' in the thread code, you have a state shared between two threads and it's just a mess.
You can consider using async Receive instead: the socket thread posts a BeginReceive then waits on an event. The event is signaled by either the Receive completion or by the send queue having something 'dropped' in (or you can wait on multiple events, same thing basically). Now this would work, but at this moment you have a half-breed, part async part one-thread -per-socket. If you go down this path, I'd go the whole 9 yards: make the server fully async.
Going fully async would be the best solution. Instead of exchanging data between threads, completion routines operate on locked data. The Connection1 BeginReceive completes when it receives data, you parse the received data and analyze the content, then decide to send it on Connection2. So you invoke BeginSend on Connection2's socket, meaning the thread that received the data also send the data. This is much more efficient ans scales better than the thread-per-socket model, but the big disadvantage is that is just plain complicated if you're mot familiar with async and multithreaded programming.
See Asynchronous Server Socket Example and Asynchronous Client Socket Example for a primer.
What you are describing as asynchronous messaging. Microsoft has already written an app for this called MSMQ
I would use WCF on .NET 3.5 for this task, it will be more scalable. I'm using WCF for a lot of my works and its flawless. The good thing about it is you can share your data across any platform.
http://msdn.microsoft.com/en-us/netframework/aa663324.aspx