I was wondering what the best way to write an application would be. Basically, I have a sports simulation project that is multi-threaded and can execute different game simulations concurrently.
I store my matches in a SQLite database that have a DateTime attached to it.
I want to write an application that checks every hour or so to see if any new matches need to be played and spawns those threads off.
I can't rely on the task scheduler to execute this every hour because there are objects that the different instances of that process would share (specifically a tournament object), that I suspect would be overwritten by a newer process when saved back into the DB. So ideally I need to write some sort of long-running process that sleeps between hours.
I've written my object model so that each object is only loaded once from memory, so as long as all simulation threads are spawned from this one application, they shouldn't be overwriting data.
EDIT: More detail on requirements
Basically, multiple matches need to be able to run concurrently. These matches can be of arbitrary length, so it's not necessary that one finishes before the other begins (in fact, in most cases there will be multiple matches executing at the same time).
What I'm envisioning is a program that runs in the background (a service, I guess?) that sleeps for 60 minutes and then checks the database to see if any games should be started. If there are any to be started, it fires off threads to simulate those games and then goes back to sleep. Hence, the simulation threads are running but the "scheduling" thread is sleeping for another 60 minutes.
The reason I can't (I think) use the default OS task-scheduling interface is that these require the task to be executed to be spurned as a new process. I have developed my database object model such that they are cached by each object class on first load (the memory reference) meaning that each object is only loaded from memory once and that reference is used on all saves. Meaning that when each simulation thread is done and saves off its state, the same reference is used (with updated state) to save off the state. If a different executable is launched every time, presumably a different memory reference will be opened by each process and hence one process could save into the DB and overwrite the state written by the other process.
A service looks like the way to go. Is there a way to make a service just sleep for 60 minutes and wake up and execute a function after that? I feel like making this a standard console application would waste memory, but I don't know if there is an efficient way to do that which I'm not aware of.
If you want to make it really reliable, make it a Service.
But I don't see any problems in making it a normal (Console, WinForms, WPF) application.
Maybe you could expand on the requirements a little.
The reason I can't (I think) use the default OS task-scheduling interface is that these require the task to be executed to be spurned as a new process. I have developed my database object model such that they are cached by each object class on first load (the memory reference) meaning that each object is only loaded from memory once and that reference is used on all saves
If you want everything to remain cached forever, then you do need to have an application that simply runs forever. You can make this a windows service, or a normal windows application.
A windows service is just a normal exe that conforms to the service manager API. If you want to make one, visual studio has a wizard which auto-generates some skeleton code for you. Basically instead of having a Main method you have a Service class with a Run method and everything else is the same.
You could, if you wanted to, use the windows task scheduler to schedule your actions. The way you'd do this is to have your long-running windows service in the background that does nothing. Have it open a TCP socket or named pipe or something and just sit there. Then write a small "stub" exe which just connects to this socket or named pipe and tells the background app to wake up.
This is, of course, a lot harder than just doing a sleep in your background application, but it does let you have a lot more control - you can change the sleep time without restarting the background service, run it on-demand, etc.
I would however, consider your design. The fact that you rely on a long-running service is a large point of failure. If your app needs to run for days, and you have a single bug which crashes it, then you have to start again. A much better architecture is to follow the Unix model, where you have small processes which start, do one thing, then finish (in this case, process each game simulation as it's own process so if one dies it doesn't take the master process or the other simulations down).
It seems like the main reason you're trying to have it long-running is to cache your database queries. Do you actually need to do this at all? A lot of the time databases are plenty fast enough (they have their own caches, which are plenty smart). A common mistake I've seen programmers make is to just assume that something like a database is slow, and waste a pile of time optimizing when in actual fact it would be fine
Related
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'm working on about 35 batches updating many databases as a part of our daily process at work. Every batch of them was developed in a single web app. Due to database issues, i have collected all of them in one windows application to make use of DB connection pooling and i have assigned a single backgroundworker for each batch. Reaching to 20 batch in the application, every thing is working good. But when i add any other backgroundworker for any other batch, the application hangs.I think this is because i'm running too many threads in one process. Is there a solution for this problem, for example, making the application working with many processes ??!!!.
Regards,
Note,
I have assigned a single machine for this application (Core i7 cpu, 8 gb ram).
How many databases you have to update?
I think it is more recommended to have the number of Threads as the number of Databases
If your UI is freezing while many background workers are active, but recovers when those background workers are finished processing, then likely the UI thread is executing a method which waits for a result or signal from one of the background worker threads.
To fix your problem, you will have to look for UI-related code that deals with synchronization / multi-threading. This might be places where one of the many synchronization objects of .NET are being used (including the lock statement), but it could also involve "dumb" polling loops a-ka while(!worker.IsFinished) Thread.Sleep();.
Another possible reason for the freeze might be that you are running a worker (or worker-related method) accidentally in the UI thread instead in a background thread.
But you will find out when you use the debugger.
To keep the scope of your hunt for problematic methods managable, let your program run in the debugger until the UI freezes. At that moment, pause the program execution in the debugger. Look which code the UI thread is processing then, and you will have found one instance of offending code. (Whatever there is wrong, i can't tell you - because i don't know your code.)
It is quite possible that different UI-related methods in your code will suffer from the same issue. So, if you found the offending code (and were able to fix it) you would want to check on for other problematic methods, but that should be rather easy since at that point of time you will know what to look for...
I need to setup an automated task that runs every minute and sends emails in the queue. I'm using ASP.NET 4.5 and C#. Currently, I use a scheduler class that starts in the global.asax and makes use of caching and cache callback. I've read this leads to several problems.
The reason I did it that way is because this app runs on multiple load balanced servers and this allows me to have the execution in one place and the code will run even if one or more servers are offline.
I'm looking for some direction to make this better. I've read about Quartz.NET but never used it. Does Quartz.NET call methods from the application? or from a windows service? or from a web service?
I've also read about using a Windows service, but as far as I can tell, those are installed to the server direct. The thing is, I need the task to execute regardless of how many servers are online and don't want to duplicate it. For example, if I have a scheduled task setup on server 1 and server 2, they would both run together therefore duplicating the requests. However, if server 1 was offline, I need server 2 to run the task.
Any advice on how to move forward here or is the global.asax method the best way for the multi-server environment? BTW, the web servers are running Win Server 2012 with IIS 8.
EDIT
In a request for more information, the queue is stored in a database. I should also make mention that the database servers are separate from the web servers. There are two database servers, but only one runs at a time. There is a central storage they both read from so there is only one instance of the database. When one database server goes down, the other comes online.
That being said, would it make more sense to put a Windows Service deployed to both database servers? That would make sure only one runs at a time.
Also, what are your thoughts about running Quartz.NET from the application? As millimoose mentions, I don't necessarily need it running on the web front end, however, doing so allows me to not deploy a windows service to multiple machines and I don't think there would be a performance difference going either way. Thoughts?
Thanks everyone for the input so far. If any additional info is needed, please let me know.
I have had to tackle the exact problem you're facing now.
First, you have to realize that you absolutely cannot reliably run a long-running process inside ASP.NET. If you instantiate your scheduler class from global.asax, you have no control over the lifetime of that class.
In other words, IIS may decide to recycle the worker process that hosts your class at any time. At best, this means your class will be destroyed (and there's nothing you can do about it). At worst, your class will be killed in the middle of doing work. Oops.
The appropriate way to run a long-lived process is by installing a Windows Service on the machine. I'd install the service on each web box, not on the database.
The Service instantiates the Quartz scheduler. This way, you know that your scheduler is guaranteed to continue running as long as the machine is up. When it's time for a job to run, Quartz simply calls a method on a IJob class that you specify.
class EmailSender : Quartz.IJob
{
public void Execute(JobExecutionContext context)
{
// send your emails here
}
}
Keep in mind that Quartz calls the Execute method on a separate thread, so you must be careful to be thread-safe.
Of course, you'll now have the same service running on multiple machines. While it sounds like you're concerned about this, you can actually leverage this into a positive thing!
What I did was add a "lock" column to my database. When a send job executes, it grabs a lock on specific emails in the queue by setting the lock column. For example, when the job executes, generate a guid and then:
UPDATE EmailQueue SET Lock=someGuid WHERE Lock IS NULL LIMIT 1;
SELECT * FROM EmailQueue WHERE Lock=someGuid;
In this way, you let the database server deal with the concurrency. The UPDATE query tells the DB to assign one email in the queue (that is currently unassigned) to the current instance. You then SELECT the the locked email and send it. Once sent, delete the email from the queue (or however you handle sent email), and repeat the process until the queue is empty.
Now you can scale in two directions:
By running the same job on multiple threads concurrently.
By virtue of the fact this is running on multiple machines, you're effectively load balancing your send work across all your servers.
Because of the locking mechanism, you can guarantee that each email in the queue gets sent only once, even though multiple threads on multiple machines are all running the same code.
In response to comments: There's a few differences in the implementation I ended up with.
First, my ASP application can notify the service that there are new emails in the queue. This means that I don't even have to run on a schedule, I can simply tell the service when to start work. However, this kind of notification mechanism is very difficult to get right in a distributed environment, so simply checking the queue every minute or so should be fine.
The interval you go with really depends on the time sensitivity of your email delivery. If emails need to be delivered ASAP, you might need to trigger every 30 seconds or even less. If it's not so urgent, you can check every 5 minutes. Quartz limits the number of jobs executing at once (configurable), and you can configure what should happen if a trigger is missed, so you don't have to worry about having hundreds of jobs backing up.
Second, I actually grab a lock on 5 emails at a time to reduce query load on the DB server. I deal with high volumes, so this helped efficiency (fewer network roundtrips between the service and the DB). The thing to watch out here is what happens if a node happens to go down (for whatever reason, from an Exception to the machine itself crashing) in the middle of sending a group of emails. You'll end up with "locked" rows in the DB and nothing servicing them. The larger the size of the group, the bigger this risk. Also, an idle node obviously can't work on anything if all remaining emails are locked.
As far as thread safety, I mean it in the general sense. Quartz maintains a thread pool, so you don't have to worry about actually managing the threads themselves.
You do have to be careful about what the code in your job accesses. As a rule of thumb, local variables should be fine. However, if you access anything outside the scope of your function, thread safety is a real concern. For example:
class EmailSender : IJob {
static int counter = 0;
public void Execute(JobExecutionContext context) {
counter++; // BAD!
}
}
This code is not thread-safe because multiple threads may try to access counter at the same time.
Thread A Thread B
Execute()
Execute()
Get counter (0)
Get counter (0)
Increment (1)
Increment (1)
Store value
Store value
counter = 1
counter should be 2, but instead we have an extremely hard to debug race condition. Next time this code runs, it might happen this way:
Thread A Thread B
Execute()
Execute()
Get counter (0)
Increment (1)
Store value
Get counter (1)
Increment (2)
Store value
counter = 2
...and you're left scratching your head why it worked this time.
In your particular case, as long as you create a new database connection in each invocation of Execute and don't access any global data structures, you should be fine.
You'll have to be more specific about your architecture. Where is the email queue; in memory or a database? If they exist on a database, you could have a flag column named "processing" and when a task grabs an email from the queue it only grabs emails that are not currently processing, and sets the processing flag to true for emails it grabs. You then leave concurrency woes to the database.
I have a .NET 4 web application that has 3 separate projects associated – DAL, BAL, and UI. I am using Entity Framework for database interaction.
I have code that cycles through a bunch of database data, calls methods depending on what it finds, and then updates a database. I want this code to run all the time. At the same time I want users to be able to log in and run reports etc all while the code in the background is constantly running.
What is a good approach to this? Do I create a service for the code that constantly runs, a separate thread, an entirely separate project for the code that runs constantly, or a different approach..?
Also, depending on the answers given, how would I kick start the code that runs constantly? i.e. just through form load method or is there a better approach? I currently kick start the code by clicking a start button; this is fine for testing, but not going to work when in production.
You would be best suited for using Windows Services for always-running tasks.
Running code on a separate thread under IIS is not a reliable mechanism since IIS can terminate threads at will to conserve server resources.
Given your question and clarifications on other answers that:
Your solution runs in a hosted environment where you cannot install a service;
Calling it from a third server (i.e. Azure or such) is not an option for you;
You might be best off starting a thread in your Application_Start event to manage the database work. You'd probably want to ensure that this thread had some periodic idle time, so as not to take up too much of the hosted environment and ensure it's shutdown when your application ends or is restarted.
A service would really be optimal, but if you're in a hosted environment and can't/won't use another server, then that's not possible.
Use a Windows Service. Should also look into using Stored Procs for the database interactions you mentioned. In terms of kicking the Windows Service off, you can set it to automatic startup (when the OS starts) which will mean it will run until terminated.
I would only recommend a Windows Service if it will literally always be running. However, "always" usually means every x seconds / minutes / hours /days.
If x is greater than a few minutes, I would make it a Console Application and run it through the Windows Task Scheduler. This way you don't have to worry about memory leaks and a slew of other issues.
However, if it is only working with the database, I would recommend a stored procedure and a Sql Job.
I've got a windows service with only two methods - one private method DoWork(), and an exposed method which calls DoWork method. I want to achieve the following:
Windows service runs DoWork() method every 6 hours
An external program can also invoke the exposed method which calls DoWork() method. If the service is already running that method called from the service, DoWork() will again be invoked after the current method ends.
What's the best approach to this problem? Thanks!
An alternative approach would be to make use of a console application which can be scheduled by Windows task scheduler to run every 6 hours. In that case you don't waste resources to keep the Windows service running the entire time but only consume resources when needed.
For your second question: when you take the console app approach you can have it called by making use of Process.Start for example.
If the purpose of your application is only to run a specific task every six hours, you might be better off creating a command line application and creating a scheduled task that Windows runs automatically. Obviously, you could then manually start this application.
If you're still convinced you need a service (and honestly, from what I've seen so far, it sounds like you don't), you should look into using a Timer, but choose your timer carefully and read this article to get a better understanding of the timers built into .NET (Hint: Pay close attention to System.Timers.Timer).
To prevent reentry if another method tries to call DoWork() while the process is in the middle of performing its operation, look into using either a Mutex or a Semaphore.
there are benefits and drawbacks either way. my inclination with those options is to choose the windows service because it makes your deployment easier. scheduling things with the windows task scheduler is scriptable and can be automated for deployment to a new machine/environment, but it's still a little more nonstandard than just deploying and installing a windows service. you also need to make sure with task scheduler it is running under an account that can make the webservice call and that you aren't going to have problems with passwords expiring and your scheduled tasks suddenly not running. with a windows service, though, you need to have some sort of checking in place to make sure it is always running and that if it restarts that you don't lose hte state that lets it know when it should run next.
another option you could consider is using nservicebus sagas. sagas are really intended for more than just scheduling tasks (they persist state for workflow type processes that last for more than the duration of a single request/message), but they have a nice way of handling periodic or time-based processes (which is a big part of long running workflows). in that a saga can request that it get back a message from a timeout manager at a time it requests. using nservicebus is a bigger architectural question and probably well beyond the scope of what you are asking here, but sagas have become how i think about periodic processes and it comes with the added benefit of being able to manage some persistent state for your process (which may or may not be a concern) and gives you a reason to think about some architectural questions that perhaps you haven't considered before.
you can create a console application for your purpose. You can schedule the application to run every 6 hours. The console will have a default method called on application start. you can call your routine from this method. Hope this helps!!