"Always running" console application - c#

I wrote a console application that is currently running on the server. It doesn't require any user input (other than parameters at start which can be done via start parameter).
Unfortunately this solution is bad, because someone can accidentally turn it off (i.e. when connecting to server using Remote Desktop Connection and then logging off instead simply disconnecting). I need it to run all the time.
One solution would be to turn it into windows service, but so far using SC or third-party tools like nssm or RunAsService failed (SC and Nssm create a service but such service cannot be started).
I could completely rewrite my program to be a proper service... but to be honest I'm struggling with it (and from what I've read its not recommended practice).
Finally I could leave it as a console app and use task scheduler to run it -which does look like a decent solution, but (like I've mentioned) I need it to run all the time (it can be turned off and on - very short downtimes are not an issue).
Could I please ask for any help with setting such task?
SOLVED
After few attempts I've turned it into service using Topshelf andthis great guide.

There are two methods you can use to run a .net program constantly in windows. Both have advantages and disadvantages.
Windows Service
Recommended Solution
Will startup service on computer start (doesn't require someone to log on)
Has some (limited) error handling in the form of restarts
Good for very reliable services that can run for long periods of time
Service handles its own state
Can easily crash due to memory leaks
IIS Application Server
Not recommended solution
Starts with windows, but might not start your application
Requires newer windows to allow always on configuration
Always on configuration is complicated
State is handled by IIS
Much better resiliency to crappy programming, as IIS will restart for you
IIS will also likely kill your threads for you (so your scheduler will stop working)
I suspect the reason you were told that a windows service is not recommended was due to the fact that it could crash due to memory leaks. But that issue will occur no matter what, since your program needs to run for a long time (its not a problem with windows services, but long lived processes).

There are a number of rules that need to be followed to write a functional windows service including but not limited to
the ability to complete the initialization process in a specific time
a general understanding of threads
There is nothing inherently bad about writing a windows service they just require more effort and an installer.
Based on your description a scheduled job seems to fit your requirements

If you don't want to re-write your console app into a windows service and want it to be running all the time, the only solution I could see is:
Create a small window's service, that checks to see if your console process is running or not.
If it finds that there is no Console process, then start a new one.
Process[] pname = Process.GetProcessesByName("YourConsoleApp.exe");
if (pname.Length == 0)
Process.Start("YourConsole.exe")
else
//Do nothing

Related

Does it make sense to run a c# worker service in docker?

I am developing a multi-container app in docker. One of the services is a long-running console application in C# which basically does some polling on a database and sending the data to e server. I just keep the service running by adding this statement:
while(true);
Now I'm thinking of changing this service to a .NET Core worker service (or even windows service, since I am only using windows containers on windows hosts). I have read some articles about the pros of worker services, but they seem all quite obselete when it comes to a containerized application since my container anyway is running as kind of a "background service" (and i only use one service per container/image). So my question is:
Is there any benefit or drawback when running a core worker service in docker compared to running a console app in docker?
Update: With "worker service" I refer to the new worker service template available in .NET Core 3.x: https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
In short, your happy path code will probably function "about the same".
However:
The benefit of going to the "generic host" is you get the benefit of the reusable components Microsoft has created for you......instead of rolling your own.
This means (IMHO) better code because you are not personally dealing with alot of the common issues with a long running process.
basically, you're getting a lot of plumbing code "for free" vs rolling your own implementation.
Pre 3.0/3.1 alot of this functionality was married into the asp.net namespaces. The 3.0/3.1 updates is alot of "get this into a common place for both asp.net and .net (non asp.net)" for use. Aka, demarry it from asp.net.
Setup: (a dedicated method "AddHostedService")
services.AddHostedService<MyWorkerThatImplementsIHostedService>();
So when a future developer looks at that above code, they know exactly what is going on. (vs figuring out the custom rolled implementation)
Or in a larger code example:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<MyWorkerThatImplementsIHostedService>();
});
}
The above code ~~looks~~ asp.net'ish, but it is actually .net (non asp.net) code.
Aka, you're getting improved consistency.
Shut Down:
You get all the "shut down" options built in. And these are "graceful" shut down options... which unfortunately is not usually considered for "happy path" developers. If there is any reason to jump into this mini library...having some kind of GRACEFUL exit would be it. A hard-exit might leave your processing in an unknown hard-to-trouble-shoot state.
CNLT-C
Programmatically (see https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostapplicationlifetime.stopapplication?view=dotnet-plat-ext-3.1 )
Kubernetes Shutdown
Microsoft has even thought out "can I delay the ultimate shutdown some"
See : How to apply HostOptions.ShutdownTimeout when configuring .NET Core Generic Host?
Here is a decent link that shows some options (Timer vs Queue vs Monitor)
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio
You can also deploy your code as :
Container
Windows Service
** Linux Daemon (see https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.systemd.systemdhelpers.issystemdservice?view=dotnet-plat-ext-3.1 ) (this is usually a new concept to traditional dotnet framework developers)
Azure App Service
Oh yeah, Microsoft has even thought out "HealthChecks" for you.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-5.0#separate-readiness-and-liveness-probes-1
Bottle line, use this instead of custom rolled stuff. It is well thought out.
::::::::::::::::::::Previous Comments:::::::::::::::::::::::::::::::::(below)
...............
Long-running console application in C#
Short version:
With modern code deployment strategies, it's not just technical decisions, it's financial decisions.
Longer version:
I've had this discussion recently, as some code bases have been earmarked for "convert to dotnet core" and "how do we convert our older windows services?".
Here are my thoughts:
Philosophically.
You have to think of "where I deploy and how much does that cost?", not just the technical problem. You mention docker. But how are you doing to deploy it? Kubernetes? (AKS in azure, other?) That's an important piece of information.
IMHO: With the "cloud" or even on premise Kubernetes.... you do NOT want a "Windows service" mentality, that will just run and run and run, running up costs constantly. Unless you have to have this.
You want to startup a process, let it run, and close it down as soon as possible.
Now, if you need it to run every hour, that's fine.
Now, if you need "instant" or "as soon as possible processing", (like watching for messages on a queue), then maybe you pay the price and have something that runs all of time, because processing those messages is more important than the price you pay for the running services.
So technically, I like the idea of
https://www.stevejgordon.co.uk/what-are-dotnet-worker-services
WHAT ARE WORKER SERVICES? Applications which do not require user
interaction. Use a host to maintain the lifetime of the console
application until the host is signalled to shut down. Turning a
console application into a long-running service. Include features
common to ASP.NET Core such and dependency injection, logging and
configuration. Perform periodic and long-running workloads.
But financially, I have to counter that with the cost of running on Azure (or even on premise).
Processing Message Queue messages means --> "yep, gotta run all the time". So I pay the price of having it run all the time.
If I know my client posts their import files in the middle of the night, one time, then I don't want to pay that price of always running. I want a console app that fires once in the morning. Get in, get out. Do the processing as quick as possible and get out. Kubernetes has scheduling mechanisms.
With Azure, it's not just technical decisions, it's financial decisions.
Not mentioned: if your code is scheduled to run every hour, but then starts taking longer than hour to run, you have different issues. Quartz.Net is one way to deal with these overlap issues.
Keep in mind, I had to really be firm about this argument about cost. Most developers just wanted to convert the windows-services to dotnet-core and be done with it. But that is not long term thinking as more code moves to the cloud and the cost of cloud operation come into play.
PS
Also, make sure you move all your code DOWN INTO A BUSINESS LAYER........and let any of these methods
Console.App (just regular one)
.NET Core worker service
Quartz.Net schedule job
Let the above items be "thin top layer that call your business logic layer", and then you don't paint yourself into a corner. The thinner you make that top layer, the better. Basically, my console-apps are
void Main(string args)
{
//wire up IoC
//pull out the business logic layer object from the Ioc
//call a single method on the business logic layer
}
and some appsettings.json files were Program.cs sits. Nothing or very little else. Push everything down to the business logic layer as soon as possible.
If you are always going to run in a container, then go with a console app. I see no inherent benefit of running as a service since containers, under proper orchestration such as Kubernetes, should be considered ephemeral. Also, you will have less friction in running your .NET Core 3.1.x application as a Linux or Windows container if you keep it simple i.e. console.
Also, I would use the following line in your console to ensure it plays nice with the allocated CPU for the container:
while(true)
{
Thread.Sleep(1 * 1000);
}

Design of background client application

I am having to design a client application that will be installed on all computers in our company that will collect and report hardware and software information for inventory purposes to a SQL database. The application may need to be updated remotely and possibly some parameters such as polling time period be updated remotely as well. I am not entirely sure of the best way to architect this type of application. In trying to research and think this through I have come up with the following options:
write a Windows Service that would always run automatically, anytime a computer booted up and on a Timer have it perform the necessary inventory functions.
write a Windows Service that acts like base platform for future expansions, but contain the actual inventory client in a Forms/WPF app that is minimized to the system tray and can be opened to change settings. The Windows Service would verify that the Forms/WPF app is always running and handle any management tasks such as possibly performing upgrades on the Forms/WPF app.
write just a Forms/WPF app that is configured to run on Startup. It would be minimized to the system tray and on a timer perform the inventory function and report to the database.
That is the three main options I have come up with. I'm hoping someone who has tackled a problem like this in the past can provide some insight into how they designed their project. Any advice is much appreciated.
In case anyone else has a similar question, the path I've ended up taking is to create a Windows Service that has all of its main logic in a separate dll and has a separate program for updating. The Update program stops the service, moves/overwrites the dll's for the service and then restarts the service. The main dll that the Service runs processes on a polling/timer feature and periodically checks for and downloads updates and then can schedule the Update program to run. I found a great example here.
Even though I've already chosen how I am going to implement this project, I am still open to hearing how others have handled similar situations.

windows service vs scheduled tasks

So this is my first stint with programmatically creating windows service or scheduled tasks and I am confused which one to choose. I had a look at various articles like http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx , scheduled task or windows service and some more but can' t really decide btween the two
Here is my scenario :
My application will pick up the code paths of a few dlls from the db , execute the DLLs using MSTest.exe and log back the results to the Db. this will probably be repeated every 2-3 hours . Now I am leaning a bit towards scheduled tasks since i won't have to worry about memory related issues but need some expert advice on this.
P.S. : The DLLs contain test methods that make calls to web services of applications deployed on various servers
Thanks in advance for the help
A Scheduled Task would be more appropiate for your scenario. I don't think it make a lot of sense building a scheduling mechanism on a windows service when OS already provides scheduling infraestructure.
A Windows service is more appropiate for processes that have to respond to events at any moment and not at specific and fix periods. That's why they are running all the time. An example of this is the SQL Server Service.
An exception of this could be a task that needs to run every second or so. In that corner case, a Window Service could be the best solution. For your specific schedule, I have no doubts that a scheduled task would fit much more better.
Although this post is several months old, here's a possible resolution in case it's helpful to others for the "Run whether the user is logged on or not" issue : start with a console project then change type to Windows App as mentioned at Run code once and exit formless app: Windows Forms or WPF... does it matter?:
“If you never show a UI, you should start with a WinForms project (WPF projects set extra project metadata that you don't want), then delete the reference to System.Windows.Forms.dll. Alternatively, start with a console project, then change the Output type to Windows Application.”

running timer from global.asax vs quartz.net

I am developing a asp.net site that needs hit a few social media sites daily for blanket friend/follower data. I have chosen arvixe business class as my hosting. In the future if we grow, I'd love to get onto a dedicated server and run a windows service, however since that is not in the cards at this point I need another reliable way of running scheduled tasks. I am familiar with running a thread timer from the app_code(global.aspx). However the app pool recycling will cause some problems with the timer. I have never used task scheduling like quartz but have read a lot about it on stackoverflow. I was looking for some advise as to how to approach my goal. One big problem I have using either method is that I will need the crawler threads to sleep for up to an hour regularly due to api call limits. My first thoughts were to use the db to save the starting and ending of a job. When the app pool recycles I would clear out any parts not completed and only start parts that do not have a record of running on that day. What do the experts here think? any good links to sample architecture of this type of scheduling?
It doesn't really matter what method you use, whether you roll your own or use Quartz. You are at the mercy of ASP.NET/IIS because that's where you want to host it.
Do you have a spare computer laying around that can just run a scheduled task and upload data to a hosted database? To be honest, it's possibly safer (depending on your use case) to just do it that way then try to run a scheduler in ASP.NET.
Somewhat along the lines of Bryan's post;
Find a spare computer.
Instead of allowing DB access have it call up a web service on your site. This service call should be the initiator of the process you are trying to do. Don't try to put params into it, just something like "StartProcess()" should work fine.
As far as going to sleep and resuming later take a look at Workflow Foundation. There are some nice built in features to persist state.
Don't expose your DB to the outside world, instead expose that page or web service and wraps some security around that. WCF has some nice built in security features for that.
The best part is when you decide to move off, you can keep your web service and have it called from a Windows Service in the same manner.
As long as you use a persistent job store (like a database) and you write and schedule your jobs so that they can handle things like being killed half way through, having IIS recycle your process is not that big a deal.
The bigger issue is that IIS shuts your site down if it doesn't have traffic. If you can keep your site up, then just make sure you set the misfire policy appropriately and that your jobs store any state data needed to pick up where they left off, you should be able to pull it off.
If you are language-agnostic and don't mind writing your "job-activation-script" in your favourite, Linux-supported language...
One solution that has worked very well for me is:
Getting relatively cheap, stable Linux hosting(from reputable
companies),
Creating a WCF service on your .Net hosted platform that will contain the logic you want to run regularly (RESTfully or SOAP or XMLRPC... whichever suits you),
Handling the calls through your Linux hosted cron jobs, written in your language of choice(I use PHP).
Working very well, like I said. No VPS expense,configurable and externally activated. I have one central place where my jobs are activated, with 99 to 100% uptime(never had any failures).

Best Practices of fault toleration and reliability for scheduled tasks or services

I have been working on many applications which run as windows service or scheduled tasks.
Now, i want to make sure that these applications will be fault tolerant and reliable. For example; i have a service that runs every hour. if the service crashes while its operating or running, i d like the application to run again for the same period (there are several things involved with this including transactions of data processing) , to avoid data loss. moreover, i d like the program to report the error with details. My goal is to avoid data loss and not falling behind for running the program.
I have built a class library that a user can import into a project. Library is supposed to keep information of running instance of the program, ie. program reads and writes information of running interval, running status etc. This data is stored in a database.
I was curious, if there are some best practices to make the scheduled tasks/ windows services fault tolerant and reliable.
Edit : I am talking about independent tasks or services which on different servers. and my goal is to make sure that the service will keep running, report any failures and recover from them.
I'm interested in what other people have to say, but I'll give you a few points that I've stumbled across:
Make an event handler for Unhandled Exceptions. This way you can clean up resources, write to a log file, email an administrator, or anything you need to instead of having it crash.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppUnhandledExceptionEventHandler);
Override any servicebase event handlers you need in the main part of your application. OnStart and OnStop are pretty crucial, but there are many others you can use. http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase%28v=VS.71%29.aspx
Beware of timers. Windows forms timers won't work right in a service. User System.Threading.Timers or System.Timers.Timer. Best Timer for using in a Windows service
If you are updating on a thread, make sure you use a lock() or monitor in key sections to make sure everything is threadsafe.
Be careful not to use anything user specific, as a service runs without a specific user context. I noticed some of my SQL connection strings were no longer working for windows authorizations, etc. Also have heard people having trouble with mapped drives.
Never make a service with a UI. In fact for Vista and 7 they make it nearly impossible to do anyway. It shouldn't require user interaction, the most you can do is send a message with a WIN32 function. MSDN claims making interactive services is bad practice. http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx
For debugging purposes, it is way cool to make a service run as a console application until you get it doing what you want it to. Awesome tutorial: http://mycomponent.blogspot.com/2009/04/create-debug-install-windows-service-in.html
Anyway, hope that helps a little, but that is just a couple thing I poked around to find on my own.
Something obvious - don't run all your tasks at the same time. Try to schedule them so only one task is using some expensive resource at any time (if possible). For example, if you need to send out newsletters and some specific notifications, schedule them at different times. If two tasks need to clean up something in the database, let the one run after another.
Also schedule tasks to run outside of normal business hours - at night obviously.

Categories