The simplest possible infinitely repeat - c#

I need the simplest possible Timer to repeat my code infinitely every 5 seconds. No external classes or whatnot.
Just:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Now the following code will be repeated over and over");
//////////////// FOLLOWING CODE /////////////////
/* the repeated code */
//////////////// END OF FOLLOWING CODE /////////////////
}
}
How can I do that?

Use while(true) with Thread.Sleep
using System.Threading;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Now the following code will be repeated over and over");
while(true)
{
//////////////// FOLLOWING CODE /////////////////
/* the repeated code */
//////////////// END OF FOLLOWING CODE /////////////////
Thread.Sleep(5000);
}
}
}

Simplest form of it :
using System.Threading;
static void Main(string[] args)
{
bool breakConditionFlag = false;
ManualResetEvent waitHandler = new ManualResetEvent(false);
while(breakConditionFlag)
{
//Your Code
waitHandler.WaitOne(TimeSpan.FromMilliseconds(1000)); // 1000 is the Arbitary value you can change it to Suit your purpose;
}
}
Why ManualResetEvent ?
The event makes more efficient use of the processors- you're not having to wake the parent thread up to poll. The kernel will wake you up when the event fires.

Use Timer.
static void Main(string[] args)
{
Timer timer = new System.Threading.Timer((e) =>
{
Console.WriteLine("Now the following code will be repeated over and over");
}, null, 0, (int)TimeSpan.FromSeconds(5).TotalMilliseconds);
Console.Read();
}
Here I have called Console.WriteLine multiple times, you can write your code block instead of it.
You can use Thread.Sleep(5000); But again its also external class according to the OP.
But I would suggest a better solution using Async and Await. One more thing you should have a termination condition, so that you dont produce an infinite call to avoid unnecessary memory consumption.
public static async Task RepeatActionEveryInterval(Action action, TimeSpan interval, CancellationToken cancelToken)
{
while (true)
{
action();
Task task = Task.Delay(interval, cancelToken);
try
{
await task;
}
catch (TaskCanceledException)
{
return;
}
}
}
static void Main(string[] args)
{
CancellationTokenSource cancelToken = new CancellationTokenSource(TimeSpan.FromSeconds(50));
Console.WriteLine("Start");
RepeatActionEveryInterval(() => Console.WriteLine("Repeating Code"), TimeSpan.FromSeconds(5), cancelToken.Token).Wait();
Console.WriteLine("End");
Console.Read();
}
In this example this code will write till 50 seconds.

Use this code for call your function recursively for every 5 seconds.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace recurssiveWithThread
{
class Program
{
static void Main(string[] args)
{
RecWork();
}
public static int i = 0;
public static void RecWork()
{
// Do the things whatever you needed here
i++;
Console.WriteLine(i);
//Thread to make the process to sleep for sometimes
Thread.Sleep(5000);
//Call your function here
RecWork();
}
}
}

Use BackgroundWorker class:
Reference links:
Background worker
If you are using framework >= 4.5.2 QueueBackgroundWorkItem
QueueBackgroundWorkItem

Related

Not seeing output after using Task delay

I am using an online editor for testing some C# code : https://repl.it/
I am not able to get the task after Task.Delay.
Why is this C# code not working as intended?
using System.IO;
using System;
using System.Reflection;
using System.Threading.Tasks;
class Input {
public Input() {
}
public async void hello()
{
Console.WriteLine("some task");
await Task.Delay(1000);
Console.WriteLine("after some time");
}
}
class SomeExample {
public static void Main(string[] args) {
Input std1 = new Input( );
std1.hello();
}
}
Method hello should return Task, not void. Method Main should be async Task to be able to await hello. Also you need to await std1.hello() call:
public async Task hello()
{
Console.WriteLine("some task");
await Task.Delay(1000);
Console.WriteLine("after some time");
}
public static async Task Main(string[] args)
{
Input std1 = new Input( );
await std1.hello();
}
What you have now is situation when Main method finishes its execution before hello method (because it not awaited).
Fixes: Change your method return type from void to Task. Make the console wait by adding Console.ReadLine() so that you can see the output ("after some time") and lastly, tell the method to wait and don't finish execution by adding Wait().
Hope this works.
class Input
{
public Input()
{
}
public async Task hello()
{
Console.WriteLine("some task");
await Task.Delay(1000);
Console.WriteLine("after some time");
Console.ReadLine();
}
}
class SomeExample
{
public static void Main(string[] args)
{
Input std1 = new Input();
std1.hello().Wait();
}
}
For now it seems this code is doing my work. I don't need to use async or Task keywords.
using System.IO;
using System;
using System.Threading.Tasks;
class Input
{
public Input()
{
}
public void hello()
{
Console.WriteLine("some task");
Task.Delay(1000).Wait();
Console.WriteLine("after some time");
}
}
class SomeExample
{
public static void Main(string[] args)
{
Input std1 = new Input();
std1.hello() ;
}
}

execute after x seconds - use async task or timer ticks

currently I'm using a timer to poll every x seconds. I've seen that I could also use asyncronous tasks to execute a function after x seconds.
So I've created an example for reproduction. This is how I would use a polling timer
class UseTimer
{
public UseTimer()
{
Console.WriteLine("Foo");
Timer myTimer = new Timer(2000);
myTimer.Elapsed += (object sender, ElapsedEventArgs e) =>
{
Console.WriteLine("Bar");
myTimer.Enabled = false;
};
myTimer.Enabled = true;
Console.ReadLine();
}
}
The code first logs Foo, then waits 2 seconds for the first timer tick and then logs Bar. I tried to reproduce it by using async/await
class UseAsync
{
public UseAsync()
{
Console.WriteLine("Foo");
Do().Wait();
Console.ReadLine();
}
private async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
The behaviour seems to be the same when I test it with this code
class Program
{
static void Main(string[] args)
{
// UseAsync a = new UseAsync();
UseTimer t = new UseTimer();
}
}
I would like to know if I could or even should switch to async because it's easier to maintain and takes out complexity but remains the same way under the hood.
"Every x seconds" is different from "after x seconds".
If you need to run something (repeatedly) every x seconds, use a Timer.
If you need to run something (only once) after x seconds, use Task.Delay.
As noted in the comments, Task.Delay uses a System.Threading.Timer anyway, it's just easier to use for a single wait, and keeps your code clean.
Also, it's not wise to use asynchronous methods in a class constructor. Class constructors cannot be async, and thus you end up blocking the thread (as you did when using Wait()), or "fire and forget". If you need to do anything asynchronous while creating a new object, you can use a "factory method": a static method that creates the object for you. Then you make the constructor private to force everyone to use the factory method:
class UseAsync
{
private UseAsync() {}
public static async Task<UseAsync> CreateUseAsync()
{
var myC = new UseAsync();
await myC.Do();
return myC;
}
private async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
Then you can create an instance like this:
var a = await UseAsync.CreateUseAsync();
I've done this when I need to retrieve data from somewhere before an object is actually useful.
The console.readline should be outside useAsync method, if not the task Do will not be executed
class Program
{
static void Main(string[] args)
{
UseAsync.UseAsyn();
Console.ReadLine();
}
}
static class UseAsync
{
public static async Task UseAsyn()
{
Console.WriteLine("Foo");
await Do();
}
private static async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}

Windows Service performing work on a timer with graceful shutdown

I am trying to create a Windows Service that executes a job on a timer and has graceful shutdown. I've used various questions/answers on here to come up with the code below. It works but I want to make sure it's the most correct and elegant solution. And I have specific questions too (after code).
This is the main service class.
using System;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
namespace MyService
{
public class MyService : ServiceBase
{
CancellationTokenSource cancellationTokenSource;
System.Timers.Timer serviceTimer;
Task workTask;
public static void Main(string[] args)
{
if (!Environment.UserInteractive)
{
Run(new MyService());
}
}
protected override void OnStart(string[] args)
{
cancellationTokenSource = new CancellationTokenSource();
serviceTimer = new System.Timers.Timer(30000);
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();
}
protected override void OnStop()
{
try
{
serviceTimer.Stop();
cancellationTokenSource.Cancel();
if (workTask != null)
{
workTask.Wait(10000);
}
}
finally
{
serviceTimer.Dispose();
serviceTimer = null;
cancellationTokenSource.Dispose();
cancellationTokenSource = null;
}
}
private void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
serviceTimer.Stop();
workTask = Task.Run(() => StartWorkMethod()).ContinueWith(WorkCompleted);
}
private void WorkCompleted(Task completedTask)
{
workTask = null;
serviceTimer.Start();
}
private void StartWorkMethod()
{
Work work = new Work(cancellationTokenSource.Token);
work.StartWork();
}
}
}
This is the class that performs the (currently simulated) work.
using System.Threading;
namespace MyService
{
public class Work
{
CancellationToken cancellationToken;
public Work(CancellationToken cancellationToken)
{
this.cancellationToken = cancellationToken;
}
public void StartWork()
{
for (int i = 0; i < 4; i++)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
Thread.Sleep(10000);
}
}
}
}
The service works and runs all tasks without blocking the handler threads. If the service is stopped, the OnStop method will wait for the task's current block of work to complete for a certain period of time before stopping anyways (thanks Ian of Oz!).
Here are my specific questions:
To prevent the service from stopping immediately and waiting for the current block to complete, I am using the working variable and a while loop to wait for the Work class to complete and the bool to be set to false. Is this the best way to handle this? Already answered by Ian of Oz.
I also want to have a "feature" where if the current block is taking too long to complete, the OnStop method will only wait a certain amount of time before exiting anyways. What is the best way to implement that? Already answerd by Ian of Oz.
I've tried to make sure I handle all threading issues with my code. Is there anything I missed or that might cause trouble later with this implementation?
Also some notes to avoid any confusion:
Service install code is not included, I am using an installer to install the service.
The timer controls the time between executions so that there aren't overlapping executions if the previous execution takes longer; this is why the timer stops before starting the work and restarts after.
I've seen where the Main method is sometimes placed in it's own file, but mostly where the executable is also the installer; in this case it would only simplify this file by the Main method itself.
Edited to incorporate suggestion from Ian of Oz.

executing a block of code repeatedly without a timeout. windows service

I have a simple windows service written, here is its skeleton:
internal class ServiceModel {
private Thread workerThread;
private AutoResetEvent finishedEvent;
private Int32 timeout = 60000*15;
public void Start() {
this.workerThread = new Thread(this.Process);
this.finishedEvent = new AutoResetEvent(false);
this.workerThread.Start();
}
public void Stop() {
this.finishedEvent.Set();
this.workerThread.Join(30000);
}
public void Process() {
while(!this.finishedEvent.WaitOne(timeout)) {
// run things here
}
}
}
the first thing
The first thing that I can't understand is that service waits one timeout before running. Would rewriting the new AutoResetEvent(false); to new AutoResetEvent(true); cause a service to start without waiting?
the second thing
Due to some internal reasons (requesting data from external server/service, exception handling) sometimes it is not enough to wait that fixed 15..30-minutes timeout.
How do I rewrite it to work without a fixed timeout?
Do I need to remove that AutoResetEvent instance at all and run Process body inside an infinite loop?
public void Process() {
while(true) {
// run things here
}
}
edit. try-catch/lock
In Process method there is a global try-catch block:
public void Process() {
do {
try {
// processing goes here
}
catch(Exception ex) {
Logger.Log.Warn(ex); // or Log.Fatal(ex)...
}
}
while(true);
}
if I use a synchronization object where do I put the lock statement so that I'm able to call break when isStopped is true?
You don't have to deal with low-level thread and synchronization primitives API. Consider using Task Parallel Library (TPL). It's easy to implement OnStop using TPL cancellation framework:
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
CancellationTokenSource _mainCts;
Task _mainTask;
public Service1()
{
InitializeComponent();
}
async Task MainTaskAsync(CancellationToken token)
{
while (true)
{
token.ThrowIfCancellationRequested();
// ...
await DoPollingAsync(token);
// ...
}
}
protected override void OnStart(string[] args)
{
_mainCts = new CancellationTokenSource();
_mainTask = MainTaskAsync(_mainCts.Token);
}
protected override void OnStop()
{
_mainCts.Cancel();
try
{
_mainTask.Wait();
}
catch
{
if (!_mainTask.IsCanceled)
throw;
}
}
}
}
Inside MainTaskAsync you can use Task.Run for any CPU-bound work items.
using Threads you can achieve your requirement using the following code:
internal class ServiceModel {
private Thread workerThread;
private object syncLock = new object();
private bool stop = false;
public void Start() {
this.workerThread = new Thread(this.Process);
this.workerThread.Start();
}
public void Stop() {
lock(syncLock) stop = true;
this.workerThread.Join(30000);
}
public void Process() {
while(true){
//your stuff here.
lock(syncLock)
{
if(stop)
break;
}
Thread.Sleep(30000);
}
}
}

Monitor.Wait timeout never times out

So I have a simple test using Monitor.Wait with a timeout set for three seconds. It's my understanding that, when the time expires, a virtual pulse is sent to the monitor to release the wait. In my test, however, that never seems to happen. Can someone explain what's going on. Here's my test code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace BlockingMethodFoo
{
class Program
{
static void Main(string[] args)
{
WaitFoo foo = new WaitFoo();
foo.StartMethod();
Console.WriteLine("Done. Press enter");
Console.ReadLine();
}
}
public class WaitFoo
{
private object _waitObj = new object();
private string _message = string.Empty;
public void StartMethod()
{
Thread waitThread = new Thread(new ThreadStart(new Action(() => { WaitMethod(); })));
_message = string.Empty;
Console.WriteLine("Starting wait");
_message = "Time Out";
lock (_waitObj)
{
waitThread.Start();
Monitor.Wait(_waitObj, TimeSpan.FromSeconds(3));
}
Console.WriteLine(_message);
}
private void WaitMethod()
{
lock (_waitObj)
{
_message = Console.ReadLine();
Monitor.Pulse(_waitObj);
}
}
}
}
Monitor.Wait will return false if the timeout expires and it couldn't get the lock.
http://msdn.microsoft.com/en-us/library/tdc87f8y.aspx
You have to check the return of Monitor.Wait and for example throw a TimeOutException if you see fit.

Categories