How can I use a timer in my console application? - c#

How can I use a timer in my console application? I want my console application to work in the background and to do something every 10 minutes, for example.
How can I do this?
Thanks

Console applications aren't necessarily meant to be long-running. That being said, you can do it. To ensure that the console doesn't just exit, you have to have the console loop on Console.ReadLine to wait for some exit string like "quit."
To execute your code every 10 minutes, call System.Threading.Timer and point it to your execution method with a 10 minute interval.
public static void Main(string[] args)
{
using (new Timer(methodThatExecutesEveryTenMinutes, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)))
{
while (true)
{
if (Console.ReadLine() == "quit")
{
break;
}
}
}
}
private static void methodThatExecutesEveryTenMinutes(object state)
{
// some code that runs every ten minutes
}
EDIT
I like Boj's comment to your question, though. If you really need a long-running application, consider the overhead of making it a Windows Service. There's some development overhead, but you get a much more stable platform on which to run your code.

You can just use the Windows Task Scheduler to run your console application every 10 minutes.

Related

How to run code periodically in the background in Tizen 5.5?

I need to run a code every x minutes and show a notification if needed.
How can I run a code in the background periodically while the app is closed?
So far what I've reached to is that I lock the CPU and call a timer to run periodically. The problem with this is that it drains the battery and the watch shows a notification suggesting to close the app.
public static void LockCpu()
{
Power.RequestLock(PowerLock.Cpu, 0);
}
public static void ReleaseCpu()
{
Power.ReleaseLock(PowerLock.Cpu);
}
It's for Tizen .NET for wearable watches.
Thanks.
You can use the Alarm API to run code periodically.
https://docs.tizen.org/application/dotnet/guides/alarm/alarms/
https://docs.tizen.org/application/dotnet/api/TizenFX/API7/api/Tizen.Applications.AlarmManager.html
To prevent battery drain, that is not guaranteed to be accurate.

How to keep Console application open and rerun code every 5 minutes?

I have a Console application that I would like to run in the background.
I want it to keep the console open, and just execute the code every five minutes.
I don't want to use Windows Task Scheduler.
How can I do this?
Thank you
I suggest to use:
while(true)
{
//Your Code Here
Console.WriteLine("Hello World");
int milliseconds = 300000; //300000 milliseconds = 5 minutes
Thread.Sleep(milliseconds);
}

Recommended way to prevent a .Net Core 5 console app from ending when run on Linux as a service

I have a .Net Core 5 console app that runs on Linux (Debian 10). The basic structure is something like this:
class Program
{
static async Task Main(string[] args)
{
await SetupStuffAsync();
MonitorGpioService.Run();
RunAScheduledServiceOnATimer();
Console.ReadLine();
}
}
Basically, it runs on an Orange Pi Zero (similar to a Raspberry Pi), waiting for a signal on a GPIO pin. When that signal arrives, it reads the serial port for a few milliseconds, writes the data to a MariaDB database (using EF Core), and posts the data to a Web API. It also runs some scheduled maintenance code every 5 minutes (using System.Timers.Timer()).
This app runs unattended - there's not even a screen - and must run always, from the moment the Orange Pi is booted up until it is shutdown.
Console.ReadLine() worked fine in stopping the app from ending when I was manually running the app during development.
But now I need the app to run automatically when Debian starts up, so I did the following:
sudo nano /etc/systemd/system/orangePi.service
[Unit]
Description=orangePi.service
[Service]
Type=simple
ExecStart=/root/dotnet/dotnet sr/local/bin/orangePiService/orangePiService.dll
Restart=on-failure
RestartSec=10
KillMode=process
[Install]
WantedBy=multi-user.target
This works great - the app starts up automatically on bootup, but there's a problem. Console.ReadLine() is being completely ignored. It literally executes everything and then ends. I suppose this makes sense as it's not running in the console in this case.
I know I can, for example, put an infinite loop at the end to prevent it from ending:
class Program
{
static async Task Main(string[] args)
{
await SetupStuffAsync();
MonitorGpioService.Run();
RunAScheduledServiceOnATimer();
while (0 == 0) {};
}
}
And this works, but I don't like it. Not only is it not pretty, but also I would imagine that it's using up a lot of CPU to run that loop.
I could do this instead:
class Program
{
static async Task Main(string[] args)
{
await SetupStuffAsync();
MonitorGpioService.Run();
RunAScheduledServiceOnATimer();
while (0 == 0)
{
Thread.Sleep(int.MaxValue);
};
}
}
Which I would imagine would be less taxing on the CPU, but I think it's blocking this thread. Is that a problem? I know it depends on what the rest of the code looks like, but it's quite a bit of code to post here. What I can say is that most of the action happens in MonitorGpioService.Run() which I am posting below in an extremely simplified format:
using System.Device.Gpio;
public static class MonitorGpioService()
{
static GpioController _controller;
public static void Run()
{
_controller = new GpioController();
_controller.RegisterCallbackForPinValueChangedEvent((int)Settings.GpioPin.Read, PinEventTypes.Rising, onSignalPinValueChangedEvent);
}
private static void onSignalPinValueChangedEvent(object sender, PinValueChangedEventArgs args)
{
string data = ReadSerialPortFor40ms();
using (var context = new eballContext())
{
await _dbContext.Readings.AddRangeAsync(readings);
await _dbContext.SaveChangesAsync();
}
}
}
I am using awaits wherever possible, which I think wouldn't be affected by the main thread being blocked. I'm not sure about the firing of the event handler when a GPIO pin state changes though. From my testing, it doesn't appear to be affected by blocking the main thread, but I can't be sure...
In summary (and I apologize for the length of this post), I'm trying to figure out what's the best way to prevent a .Net Core console app from quitting when running on Linux as a service. And by best, I mean one that consumes as little CPU as possible, or maybe blocks threads as little as possible (assuming this is even a problem to begin with, which I'm not really sure considering most of my code runs on Timers or uses awaits).
Well, while loop is a beautiful thing but it is enemy of the CPU.
Instead of while, I often use ManualResetEvent class to prevent closing console apps.
Usually it works when i use this code block in Linux containers on Docker.
I don't have the actual code block, I am going to remember it like;
public static ManualResetEvent _Shutdown = new ManualResetEvent(false);
static void Main(string[] args)
{
//Lots of stuff.
_Shutdown.WaitOne();
}
Basically the shutdown signal never comes and console app never closes. Of course you can develop more targeted code to your needs. This prevents console app shutting down while all that stuff works. You can give it a try. Also you can find lots of different apporaches in SO.
From the answers for C# console program wait forever for event
In case of async main method, one could also use await Task.Delay(-1);
Task.Delay() itself is typically more elegant is it allows you to pass a cancellation token, enabling graceful shutdowns if needed.
Thread.Sleep() should also work, but cannot be cancelled. Instead of a while loop you can use Timeout.Infinite to suspend without wasting any cycles

How to create a scheduled long running process using windows service in c#

I want to create a windows service that performs some really long and heavy work. The code is inside OnStart method like this:
protected override void OnStart(string[] args)
{
System.IO.File.WriteAllText(
#"C:\MMS\Logs\WinServiceLogs.txt",
DateTime.Now + "\t MMS Service started."
);
this.RequestAdditionalTime(5*60*1000);
this.RunService();
}
this.RunService() sends a request to WCF service library hosted on IIS. It does some really long processes, ranging from 1-20 min, depending on the data it has to process. This service that I'm writing is supposed to be scheduled to run every day in the morning. So far, it runs and works fine, but when the time goes over a few seconds or min, it generates timeout exception. This causes the windows service to be in unstable state, and I can't stop or uninstall it without restarting the computer. Since, I'm trying to create an automated system, this is an issue.
I did do this.RequestAdditionalTime(), but I'm not sure whether it's doing what it's supposed to or not. I don't get the timeout error message, but now I don't know how to schedule it so it runs every day. If the exception occurs, then it won't run the next time. There were several articles and SO's I found, but there's something I'm missing and I can't understand it.
Should I create a thread? Some articles say I shouldn't put heavy programs in OnStart, where should I put the heavy codes then? Right now, when the service starts, it does this huge data processing which makes the Windows Service status to "Starting", and it stays there for long time until either the program crashes due to timeout, or completes successfully. How can I start the service, then set the status to Running while the code is running to do some data processing?
Your situation might be better suited for a scheduled task as Lloyd said in the comments above. But if you really want to use a Windows service, this is what you would need to add/update in your service code. This will allow your service to list as started and not timeout on you. You can adjust the timer length to suit your needs.
private Timer processingTimer;
public YourService()
{
InitializeComponent();
//Initialize timer
processingTimer = new Timer(60000); //Set to run every 60 seconds
processingTimer.Elapsed += processingTimer_Elapsed;
processingTimer.AutoReset = true;
processingTimer.Enabled = true;
}
private void processingTimer_Elapsed(object sender, ElapsedEventArgs e)
{
//Check the time
if (timeCheck && haventRunToday)
//Run your code
//You should probably still run this as a separate thread
this.RunService();
}
protected override void OnStart(string[] args)
{
//Start the timer
processingTimer.Start();
}
protected override void OnStop()
{
//Check to make sure that your code isn't still running... (if separate thread)
//Stop the timer
processingTimer.Stop();
}
protected override void OnPause()
{
//Stop the timer
processingTimer.Stop();
}
protected override void OnContinue()
{
//Start the timer
processingTimer.Start();
}

how to continuously run a c# console application in background

I would like to know how to run a c# program in background every five minute increments. The code below is not what I would like to run as a background process but would like to find out the best possible method to do this using this code so that I can implement it on another code. so this process should run after a five minute increment. I know I could use threads to do so, but dont really now how to implement this. I know this is the best way How to run a console application on system Startup , without appearing it on display(background process)? this to run in the background, but how would I have the code running in five minute increments
class Program
{
static void Main(string[] args)
{
Console.Write("hellow world");
Console.ReadLine();
}
}
This app should run continuously, putting out a message every 5 minutes.
Isn't that what you want?
class Program
{
static void Main(string[] args)
{
while (true) {
Console.Write("hellow world");
System.Threading.Thread.Sleep(1000 * 60 * 5); // Sleep for 5 minutes
}
}
}
Why not just use Windows Task Scheduler?
Set it to run your app at the desired interval. It's perfect for this sort of job and you don't have to mess about with forcing threads to sleep which can create more problems that it solves.
How about using a System.Windows.Threading.DispatcherTimer?
class Program
{
static void Main(string[] args)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 5, 0); // sets it to 5 minutes
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
static void timer_Tick(object sender, EventArgs e)
{
// whatever you want to happen every 5 minutes
}
}
Probably the simplest way to "fire" a new process every X minutes is to use Windows Task Scheduler.
You could of course do something similar programmatically, e.g. create your own service, that starts the console application every X minutes.
All this under assumption you actually want to close the application before the next iteration. Alternatively, you might just keep it active the whole time. You might use one of the timer classes to fire events periodically, or even a Thread.Sleep in a very simplified scenario....

Categories