Creating a recurring timer - c#

I have been tasked with creating a Java version of a C# SDK. Currently. I am working on a class that extends the C# System.ServiceProcess.ServiceBase but due to the difficulty of creating Windows services in Java I am focusing on some of the other methods in the class.
The current C# method I am attempting to replicate in Java looks as follows
private void StartProcesses()
{
// create a new cancellationtoken souce
_cts = new CancellationTokenSource();
// start the window timer
_windowTimer = new Timer(new TimerCallback(WindowCallback),
_cts.Token, 0, Convert.ToInt64(this.SQSWindow.TotalMilliseconds));
this.IsWindowing = true;
}
After analyzing this section of code I believe that it initializes a System.threading.Timer object that executes the WindowCallback function every SQSWindow milliseconds.
After reading through the java.util.concurrent documentation located
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html
I am unsure how I would replicate the C# functionality in Java as I cannot find the equivalent to the Timer functionality. The TimeUnit provided by the Java library appears to be only used for thread timeouts and not to issue recurring operations.
I am also curious as to the use of the CancellationTokenSource. If this object is meant to be queried to determine if the action is to continue, why is it not a primative such as a boolean? What additional functionality does it provide, and is there a similar construct in Java's multithreading model?

Using a ScheduledThreadPoolExecutor, you can get very similar functionality:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
Runnable task = new Runnable() {
public void run() {
//here the code that needs to run periodically
}
};
//run the task every 200 ms from now
Future<?> future = scheduler.scheduleAtFixedRate(task, 0, 200, TimeUnit.MILLISECONDS);
//a bit later, you want to cancel the scheduled task:
future.cancel(true);

You may want to have a look at ScheduledThreadPoolExecutor. It is an implementation of ScheduledExecutorService, which has the ability to schedule periodically.

The equivalent Java classes are `Timer and TimerTask.
Example:
Timer t = new Timer();
t.schedule(new TimerTask(){
#Override
public void run() {
// Do stuff
}
}, startTime, repeatEvery);
If you want to be able to cancel, then use the TimerTask as a variable. The TimerTask class has the method cancel.

Related

How can I execute a code in C# (Windows Service) periodically in the most precise way?

I have a code with which I am reading in 35ms intervals the current and position values of a machine's CNC axis from a remote computer.
The data is read from the CNC/PLC control system of the machine
My C# code has to run on our company server with Windows Server 2019. I am sending the data to Kafka, our AI experts have to interpret the current and position curve shapes for an AI algorithm. So the data has to be read every 35 ms as precise as possible
Normally I have used first a system timer with a 35ms period. It seems to work but I am not sure if this is the best way. Is there a more precise method than using a system timer?
My code
public void Main()
{
InitializeTimer_1();
}
public void InitializeTimer_1()
{
System.Timers.Timer timer1 = new System.Timers.Timer();
timer1.Elapsed += new ElapsedEventHandler(OnTimedEvent1);
timer1.Interval = 35;
timer1.Enabled = true;
}
public void OnTimedEvent1(object sender, EventArgs e)
{
// my Data reading code
}
There are multiple ways to solve this problem.
It first depends on what kind of application you have.
If you have a console app then you can schedule it to run every 35ms using the windows task scheduler and it will work.
If it is a long-running process like windows service then you can use the same code you have
There is one very useful library hangfire, you can explore this as well.
Also, refer to this post as well, you may get more directions.
Edit: System.Timers.Timer is sufficient for most the purpose, you could also consider System.Threading.Timer for short intervals, it allows more precise timings but its will run on a separate thread so keep that in mind. There is one more option System.Diagnostics.Stopwatch which has more high precision than other approaches.
The actual precision of the timer also depends on hardware, OS and the workload on the machine.
Now you can evaluate all the approaches and chose the best one for you.
The timer accepts a direct callback method. If you want to execute something periodic, it can be done as follows:
var timer = new Timer(TimerCallback, state, startAfterTimeSpan, repeatTimeSpan);
Where you can e.g. write a method
private void TimerCallback(object state)
{
// do something
}

A thread for updating a RichTextBox.Text twice a second is not working

First of all - I'm very low skilled programmer. I am building the foundation of a simple music app for my bachelor degree project. My question is regarding a internal clock method that is meant to increase an int value by 1 BPM times a minute.
I've created an internalClock class:
public class internalClock
{
// THIS METHOD WILL BE CALLED WHEN THE THREAD IS STARTED
public static void clockMethod()
{
int BPM = 135;
int clockTick = 1;
Form1 clockForm = new Form1();
// infinite loop
while (true)
{
if (clockTick == 8)
{
clockTick = 1;
}
else
{
clockTick++;
}
clockForm.metrobox.Text = clockTick.ToString();
Thread.Sleep(60 * 1000 / BPM);
}
}
}
This is how I managed to get an access to the RichTextBox itself:
public RichTextBox metrobox
{
get { return metroBox; }
set { metroBox = value; }
}
In the main 'Program.cs' I've written what's meant to start a separate thread to run the clockMethod until the program is closed:
// THREADING
// Create a thread
internalClock oClock = new internalClock();
Thread oClockThread = new Thread(new ThreadStart(internalClock.clockMethod));
// Start the internalClock thread
oClockThread.Start();
It's not updating the text in the RichTextBox. Also, if I call the clockMethod() without creating a separate thread for it - the application freezes. Sorry for my amateur question, I'm just getting started with C# (yeah.. my uni is useless). What am I doing wrong in my code?
So the above code has several problems, however I would encourage you to check out the Timer control that you can add to the form you want to do processing at a certain interval or in certain "ticks". MSDN Form Timer
With the timer you can remove that class you have and invoking a new thread, etc etc. I would read up on the Timer class in the given link and think about how you can re-work your application structure to fit that. The concepts for why that thread isn't working, etc, is frankly not that important for where you're at. I think you just need to focus for now on a tool that already does what you want it to do, which I believe is the Timer.
As a general note, you usually don't need to create a raw thread in .NET. As of .NET 4.0 you can access types called Tasks to perform multi-threaded logic and processing. If you find the need to do that later on, check that out. Task Type MSDN

System.Timer as a Singleton

I have data which is constantly being read by many threads. This data needs to be updated daily.
My approach has been to use a ReaderWriterLockSlim to manage access to the data. Every night the first thread to detect the day change applies a WriteLock to the data and updates it.
In order to avoid the constant check for the day change event. I would ideally like to create a System.Timer object as a singleton and have it automatically start and then execute every 24hrs thereafter.
This has been my approach:
First I extended System.Timers to execute the callback on init.
using System.Timers;
namespace Utilities
{
class AutoStartTimer : Timer
{
public AutoStartTimer(ElapsedEventHandler callback, int period):base(period)
{
callback(null, null);
AutoReset = true;
Elapsed += callback;
Enabled = true;
}
}
}
Then I declared it at a singleton where I needed it.
private static AutoStartTimer _loadDataTimer =
new AutoStartTimer(DataLoader, 86400000); // Daily
This approach is working for me so far. However I would like to know if there are any better ways to implement a Singleton Timer which executes once on initialisation and then for a set period afterwards or if anyone has managed to do this more efficiently without extending the Timer class.
I need to use many of these in my current project so I want to make sure I am using a good approach.
Thanks.
Using a static class:
public static class DayManager
{
public static readonly object SyncRoot = new object();
private static readonly Timer dayTimer;
static DayManager()
{
dayTimer = new Timer { AutoReset = true; Enabled = true; Interval = 86400000d };
dayTimer.Elapsed += OnDayTimerElapsed;
}
protected void OnDayTimerElapsed(object sender, ElapsedEventArgs e)
{
if(DayPassedEvent != null)
{
DayPassedEvent(this, null);
}
}
public event EventHandler DayPassedEvent;
}
Now, in each of the threads you should subscribe to the DayPassedEvent and use Monitor.TryEnter(DayManager.SyncRoot) to acquire a lock on the timer managing class. This means that only one thread should go on to try to update the data and the rest should fail to get the lock and continue with their lives. I'll leave the exact implementation of this up to you.
Alternatively, you could remove the SyncRoot from the timer managing class here and use another as you're already doing, I just provided it for reference only.
I have better approach for you. Use Codeplex's Lightweight Scheduler library.
A lightweight task scheduling library that allows you to easily schedule the invocation of callback methods at specified times or intervals. Supports .NET 3.5 and Silverlight.
The library allows you to include flexibule scheduling functionality into your application with just a few lines of code, and provides a fluent API to configure jobs:
Link:
http://scheduling.codeplex.com/
Other approaches:
Task Scheduler Class in .NET:
http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.aspx
http://taskscheduler.codeplex.com/
http://www.codeproject.com/Articles/1763/Task-Scheduler-Library-for-NET

Receiving packets in c# using threading

I am following a Java example that uses a Completion Service to submit queries to a 3rd party app that receives packets by calling:
completionService.submit(new FetchData());
Then it calls:
Future<Data> future = completionService.take();
Data data = future.get(timeout, TimeUnit.MILLISECONDS);
Which waits for one of the submitted tasks to finish and returns the data. These two calls are in a while(true) loop.
I am developing an app in c# and I was wondering if this is the proper way to wait for packets and if it is how do I do it in c#.
I have tried this but I'm not sure if I am doing it right:
new Thread(delegate() {
Dictionary<ManualResetEvent, FetchData> dataDict = new Dictionary<ManualResetEvent, FetchData>();
ManualResetEvent[] doneEvents;
ManualResetEvent doneEvent;
FetchData fetch;
int index;
while(true) {
// Create new fetch
doneEvent = new ManualResetEvent(false);
fetch = new FetchData(this, doneEvent);
// event -> fetch association
dataDict.Add(doneEvent, fetch);
ThreadPool.QueueUserWorkItem(fetch.DoWork);
doneEvents = new ManualResetEvent[dataDict.Count];
dataDict.Keys.CopyTo(doneEvents, 0);
// wait for any of them to finish
index = WaitHandle.WaitAny(doneEvents, receiveThreadTimeout);
// did we timeout?
if (index == WaitHandle.WaitTimeout) {
continue;
}
// grab done event
doneEvent = doneEvents[index];
// grab fetch
fetch = dataDict[doneEvent];
// remove from dict
dataDict.Remove(doneEvent);
// process data
processData(fetch.GetData());
}
}).Start();
EDIT: One last note, I am using this in Unity which uses Mono 2.6 and is limited to .NET 2.0
EDIT 2: I changed the code around some. I realized that the ThreadPool has its own max limit and will queue up tasks if there are no threads left, so I removed that logic from my code.
Do you really need to use multithread in your Unity3D application? I'm asking this because Unity "is not" multi-threaded: there's a way to deal with threads but you'd better rely on coroutines to do this. Please refer to this documentation to find more about coroutines.
One note: if you are using Unity 3.5, it uses Mono 2.6.5 that supports almost everything of .NET 4.0. I don't know about the Task class, but it certainly covers .NET 3.0.
It turns out that I only need a single thread to listen for packets, so I don't have to use a thread pool like in my example above.

Background task in a ASP webapp

I'm fairly new to C#, and recently built a small webapp using .NET 4.0. This app has 2 parts: one is designed to run permanently and will continuously fetch data from given resources on the web. The other one accesses that data upon request to analyze it. I'm struggling with the first part.
My initial approach was to set up a Timer object that would execute a fetch operation (whatever that operation is doesn't really matter here) every, say, 5 minutes. I would define that timer on Application_Start and let it live after that.
However, I recently realized that applications are created / destroyed based on user requests (from my observation they seem to be destroyed after some time of inactivity). As a consequence, my background activity will stop / resume out of my control where I would like it to run continuously, with absolutely no interruption.
So here comes my question: is that achievable in a webapp? Or do I absolutely need a separate Windows service for that kind of things?
Thanks in advance for your precious help!
Guillaume
While doing this on a web app is not ideal..it is achievable, given that the site is always up.
Here's a sample: I'm creating a Cache item in the global.asax with an expiration. When it expires, an event is fired. You can fetch your data or whatever in the OnRemove() event.
Then you can set a call to a page(preferably a very small one) that will trigger code in the Application_BeginRequest that will add back the Cache item with an expiration.
global.asax:
private const string VendorNotificationCacheKey = "VendorNotification";
private const int IntervalInMinutes = 60; //Expires after X minutes & runs tasks
protected void Application_Start(object sender, EventArgs e)
{
//Set value in cache with expiration time
CacheItemRemovedCallback callback = OnRemove;
Context.Cache.Add(VendorNotificationCacheKey, DateTime.Now, null, DateTime.Now.AddMinutes(IntervalInMinutes), TimeSpan.Zero,
CacheItemPriority.Normal, callback);
}
private void OnRemove(string key, object value, CacheItemRemovedReason reason)
{
SendVendorNotification();
//Need Access to HTTPContext so cache can be re-added, so let's call a page. Application_BeginRequest will re-add the cache.
var siteUrl = ConfigurationManager.AppSettings.Get("SiteUrl");
var client = new WebClient();
client.DownloadData(siteUrl + "default.aspx");
client.Dispose();
}
private void SendVendorNotification()
{
//Do Tasks here
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
//Re-add if it doesn't exist
if (HttpContext.Current.Request.Url.ToString().ToLower().Contains("default.aspx") &&
HttpContext.Current.Cache[VendorNotificationCacheKey] == null)
{
//ReAdd
CacheItemRemovedCallback callback = OnRemove;
Context.Cache.Add(VendorNotificationCacheKey, DateTime.Now, null, DateTime.Now.AddMinutes(IntervalInMinutes), TimeSpan.Zero,
CacheItemPriority.Normal, callback);
}
}
This works well, if your scheduled task is quick.
If it's a long running process..you definitely need to keep it out of your web app.
As long as the 1st request has started the application...this will keep firing every 60 minutes even if it has no visitors on the site.
I suggest putting it in a windows service. You avoid all the hoops mentioned above, the big one being IIS restarts. A windows service also has the following benefits:
Can automatically start when the server starts. If you are running in IIS and your server reboots, you have to wait until a request is made to start your process.
Can place this data fetching process on another machine if needed
If you end up load-balancing your website on multiple servers, you could accidentally have multiple data fetching processes causing you problems
Easier to main the code separately (single responsibility principle). Easier to maintain the code if it's just doing what it needs to do and not also trying to fool IIS.
Create a static class with a constructor, creating a timer event.
However like Steve Sloka mentioned, IIS has a timeout that you will have to manipulate to keep the site going.
using System.Runtime.Remoting.Messaging;
public static class Variables
{
static Variables()
{
m_wClass = new WorkerClass();
// creates and registers an event timer
m_flushTimer = new System.Timers.Timer(1000);
m_flushTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnFlushTimer);
m_flushTimer.Start();
}
private static void OnFlushTimer(object o, System.Timers.ElapsedEventArgs args)
{
// determine the frequency of your update
if (System.DateTime.Now - m_timer1LastUpdateTime > new System.TimeSpan(0,1,0))
{
// call your class to do the update
m_wClass.DoMyThing();
m_timer1LastUpdateTime = System.DateTime.Now;
}
}
private static readonly System.Timers.Timer m_flushTimer;
private static System.DateTime m_timer1LastUpdateTime = System.DateTime.MinValue;
private static readonly WorkerClass m_wClass;
}
public class WorkerClass
{
public delegate WorkerClass MyDelegate();
public void DoMyThing()
{
m_test = "Hi";
m_test2 = "Bye";
//create async call to do the work
MyDelegate myDel = new MyDelegate(Execute);
AsyncCallback cb = new AsyncCallback(CommandCallBack);
IAsyncResult ar = myDel.BeginInvoke(cb, null);
}
private WorkerClass Execute()
{
//do my stuff in an async call
m_test2 = "Later";
return this;
}
public void CommandCallBack(IAsyncResult ar)
{
// this is called when your task is complete
AsyncResult asyncResult = (AsyncResult)ar;
MyDelegate myDel = (MyDelegate)asyncResult.AsyncDelegate;
WorkerClass command = myDel.EndInvoke(ar);
// command is a reference to the original class that envoked the async call
// m_test will equal "Hi"
// m_test2 will equal "Later";
}
private string m_test;
private string m_test2;
}
I think you can can achieve it by using a BackgroundWorker, but i would rather suggest you to go for a service.
Your application context lives as long as your Worker Process in IIS is functioning. In IIS there's some default timeouts for when the worker process will recycle (e.g. Number of Idle mins (20), or regular intervals (1740).
That said, if you adjust those settings in IIS, you should be able to have the requests live, however, the other answers of using a Service would work as well, just a matter of how you want to implement.
I recently made a file upload functionality for uploading Access files to the database (not the best way but just a temporary fix to a longterm issue).
I solved it by creating a background thread that ran through the ProcessAccess function, and was deleted when completed.
Unless IIS has a setting in which it kills a thread after a set amount of time regardless of inactivity, you should be able to create a thread that calls a function that never ends. Don't use recursion because the amount of open functions will eventually blow up in you face, but just have a for(;;) loop 5,000,000 times so it'll keep busy :)
Application Initialization Module for IIS 7.5 does precisely this type of init work. More details on the module are available here Application Initialization Module

Categories