How do I create a process that checks date time and performs action when elapsed time passed? - c#

in my dll I'm serializing an object that I need to expire, and regenerate when x amount of days have passed.
How can I do this in a way that doesn't require the calling application to restart every day (in order to initiate the check for date time in my dll)?
using .net 3.5
private void updatePersistableItems()
{
if (!File.Exists(Items_FILENAME) && PersistableItems != null) //create new
{
_serializer.SerializeObject<PersistableObject>(Items_FILENAME, PersistableItems);
}
else //check if expired and replace, or update if not expired
{
PersistableObject ItemsFromStorage = new PersistableObject();
ItemsFromStorage = _serializer.DeSerializeObject<PersistableObject>(Items_FILENAME);
TimeSpan ts = DateTime.Now - ItemsFromStorage.DateItemsInitialized;
if (ts.TotalDays < this.DaysToPersistItems) //use stored Items
Items = ItemsFromStorage.Items;
}
}

Use a Timer to periodically call your function that does the checking: http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

You can start new Thread with while loop. Once executed on start of the application the thread can check the time amount left till content expiry, and go to sleep for the rest of the time. Once waked up after sleep, refresh content, calculate time amount left to sleep .... : )

Sounds like a job for a the task scheduler which can be controlled via c# this wrapper. Using this you can schedule the update to get run even if your application is not running all the time.

Related

How can I create a one time pipeline run with a long delay in c# data factory

I need to trigger a pipeline I have built inside of my azure data factory with certain parameters based off of a file I have stored in a database. My problem is that I need to schedule this pipeline to trigger ONCE after a certain amount of time( will usually be hours). This is needed for scheduling and I can't do it event driven. I am using the .NET SDK
I have already created a connection to my data factory and created a schedule trigger. My problem is that a schedule trigger doesn't allow me to trigger one time and then stopping. It requires intervals and a stop date, I tried to set the stop date the same as the start date but it gives me the error of "interval cannot exceed end date".
for (int x = 0; x < intervals.Count; x++)
{
// Create a schedule trigger
string triggerName = location + deliveryDate+x;
ScheduleTrigger myTrigger = new ScheduleTrigger()
{
Pipelines = new List<TriggerPipelineReference>()
{
// Associate the Adfv2QuickStartPipeline pipeline with the trigger
new TriggerPipelineReference()
{
PipelineReference = new PipelineReference(pipelineName),
Parameters = pipelineParameters,
}
},
Recurrence = new ScheduleTriggerRecurrence()
{
StartTime = intervals[x],
TimeZone = "UTC",
EndTime = intervals[x],
Frequency = RecurrenceFrequency.Day
}
};
// Now, create the trigger by invoking the CreateOrUpdate method
triggerResources.Add(triggerName,new TriggerResource()
{
Properties = myTrigger
});
}
I cannot do a pipeline run because there is not way for me to do a run after a certain delay (like 2 hours) if this was possible I would just create a delayed pipeline run...I have tried everything like leaving the frequency blank, changing it to every possibility, and even using different trigger classes like tumbling and event.
There is a simple, crude solution. Create a new pipeline with a parameter of integer type. The first activity in the pipeline will be a Wait Activity. Use the parameter to set how long the Wait Activity should last. The Second activity in the pipeline will be an Execute Pipeline Activity, which depends on the Wait Activity, and will trigger the pipeline you really want to run.
This solution lets you choose how long to wait, then execute the real pipeline you want to run. The Wait Activity is in seconds, I think, so you will need to do some arithmetic. However since you can trigger manually, it shouldn't be a problem.

Run custom "clock" / DateTime.now c#

I need to simulate a clock that is fairly precise. I need some kind of DateTime.Now, not for the local time, but for a web server's time(which can differ a few seconds from system time).
The thing is I need to be accurate, even 3 seconds is way too much difference.
Any way to create a DateTime object and then "let it run" so it shows the current server time?
PS: Not talking about a time server, but a normal web server. Can I avoid setting the system time to server time?
DateTime.Now is not very accurate, especially not for measuring time differences. »Letting it run« suggests that you actually want to use a Stopwatch and a separate DateTime as starting time. You can then generate a current timestamp by just adding your start time and the elapsed time of the Stopwatch.
So this is what I have come up with:
public class ServerTime
{
public static DateTime Now
{
get
{
if (baseTime != null)
return baseTime.Add(swatch.Elapsed);
else
return DateTime.Now;
}
set
{
baseTime = value;
swatch.Reset();
swatch.Start();
}
}
private static DateTime baseTime;
private static Stopwatch swatch = new Stopwatch();
}
Not really sure how to handle ServerTime.Now if the baseTime was not set yet.
I would probably never call this property before it was set, but as always: Don't trust your own code.

C# performing a task every hour

I have a CSV importer tool I use at my company that imports 10-20k records at a time but it can take a couple hours, the issue is that the application is connecting to an API that has an OAuth token that expires after an hour.
to me this sounds like a job for timer, but the actual code that imports and needs the oauth token are in modules since each vendor I have to upload have their own mappings to the api we use.
so I need to programmatically need to see if 3590 seconds (or 50 minutes) has passed so that I can refresh my OAuth token.
does anyone know how I can do this? if timer is not the best way to go, what way would you suggest?
it'd be nice if timer has an Elapsed property I could access from my other objects (like I can with background worker).
You could just make it part of your processing loop:
{
DateTime lastReset = DateTime.Min;
TimeSpan resetInterval = TimeSpan.FromMinutes(50);
foreach (var whatever in enumerable)
{
if ((DateTime.Now - lastReset) > resetInterval)
{
ResetAuthToken();
lastReset = DateTime.Now;
}
ProcessWhatever();
}
}
I would suggest that you can use the timer's elapsed event. This will be triggered based on the interval may be 50 minutes etc, which you can read from the configuration file of the windows service.
Then in the timer interval, you can just update a global variable [property] with the Auth token that will be used for the subsequent API calls.
In case you just want to keep the session alive, you can just refresh the token as itmse86 said. However, the timer elapsed event will come handy for you.
Reference here

Setting Reminders in Windows Phone 7 & 8 to Go Off Every Other Day

In my application I'm using the reminders service to supply reminders to the user, which prompts them to do something.
I am using the following code to do this:
if (date > DateTime.Now)
{
Reminder r = new Reminder(fileTitle);
r.Title = fileTitle;
r.Content = fileContent;
r.BeginTime = date;
ScheduledActionService.Add(r);
}
However this only goes off once. I have tried setting the ExpirationTime to a certain value, but this repeats the reminder every day.
Does anyone know how to set a reminder to fire every other day?
(In addition it would be good to know how to set reminders for certain days of the week, but the every other day part is the main issue at the moment.)
For your case I would suggest storing the time the alarm should go off. You would store this information in either the application settings or in a file. When the user first asks for the reminder to be scheduled, continue what you are doing, and then also save the time for the alarm. You may want to also ask the user when they want the alarm to stop and save that as well.
To ensure that the alarm goes off every other day, you will need to add a background agent to your application. In the agent is an OnInvoke method. In this method you will check to see if the alarm is scheduled. If it is then you have nothing to do. If it is not, then schedule it for the following day. Agents fire about every 30 minutes, so 99% of the time your agent fires, the alarm/reminder will already be scheduled.
Here is the code to place in your OnInvoke method
string fileTitle = "Foo";
string fileContent = "Bar";
var action = ScheduledActionService.Find(fileTitle);
if (action == null)
{
// shouldn't be null if it was already added from the app itself.
// should get the date the user actually wants the alarm to go off.
DateTime date = DateTime.Now.AddSeconds(30);
action = new Reminder(fileTitle) { Title = fileTitle, Content = fileContent, BeginTime = date };
}
else if (action.IsScheduled == false)
{
ScheduledActionService.Remove(fileTitle);
// most likely fired today, add two days to the begin time.
// best to also add some logic if BeginTime.Date == Today
action.BeginTime = action.BeginTime.AddDays(2);
}
ScheduledActionService.Add(action);
You need to set the RecurrenceType to a RecurrenceInterval value. Unfortunately for you, there is nothing currently available for a custom schedule (i.e. every other day).
Another duh! by Microsoft here really.

C# timer issue

Hello I'm currently having an issue with a timer in a program I'm developing. The timer runs and calls methods which retrieve Windows Management Information from remote PC's after a set period of time and repeat this.
The first time the timer calls these all is well, however the second time, after the timer has completed its task, it loops through itself again and the third time it runs it does it 3 times etc. The for loop in the code below works fine its the timer itself.
So any help would be appareciated and if you require any further details please let me know.
Below is my code:
private void tmrStore_Tick(object sender, EventArgs e)
{
string ipAdd;
ipAdd = "127.0.0.1";
List<TblServer> Server;
WMIInfo localDB = new WMIInfo("Data Source=|DataDirectory|\\WMIInfo.sdf");
Server = localDB.TblServer.ToList();
if (Server.Count == 0)
{
}
else
{
for (int counter = 0; counter < Server.Count; counter++)
{
CPUStore cpu = new CPUStore();
cpu.Store(Server[counter].IpAdd);
HDDStore hdd = new HDDStore();
hdd.Store(Server[counter].IpAdd);
MemStore mem = new MemStore();
mem.Store(Server[counter].IpAdd);
//delete items over 24 hours old
}
}
Try disabling the timer before performing the management task, then reenabling:
tmrStore.Enabled = false;
try{
// do stuff
}finally{
tmrStore.Enabled = true;
}
The cause of the problem is probably that the body of your timer handler takes longer to execute than your Timer.Ticks value, so your timer events start to stack on top of each other.
You might also consider putting this code in a thread instead of a timer, so that it's independent of your user interface.
My first guess is that you are setting your Timer.Tick event in a place that is being executed multiple times. I would try searching for "tmrStore.Tick +=" to see where all the methods are being added to the event.
Right I've resolved the issue its because I had a class I was using to write the retrieved information into text boxes and within that I called a new instance of the form to gain access to the text boxes doh!
Thanks for your help though guys no doubt I'll be back soon for some more lol

Categories

Resources