i want to truncate table using console application with parameter hour.
for example, i want to run query truncate at 12.00 AM using time in system.
this is my code in console application using c#.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string getHour = DateTime.Now.ToString("h:mm:ss tt");
if (getHour == "12:00:00 AM")
{
Console.WriteLine("Do action to run query truncate");
//in this line i will execute query truncate.
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
And this is not working. please give me solution or sample code to fix my problem.
thanks...
I would suggest few things on your code:
Don't use string comparison, but uses DateTime directly (take a look on TimeOfDay.TotalSeconds). This way, it makes the comparison a lot easier
Use repeated calls instead of just one call (unless you can really be sure that you run your program exactly at 12). This way you make your program work for you more.
To make it more robust, provide some ways to give tolerance to your system. This is how good automation should be.
Example:
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
while (true) { //read 2. assuming this is to be run forever in this example, but gives also some way to break the loop whenever necessary in your app
if (DateTime.Now.TimeOfDay.TotalSeconds <= 1) { //read 1. and 3. this way, you give tolerance of 1 second. Your action will be run on 12:00:00 - 12:00:01
Console.WriteLine("Do action to run query truncate");
// //in this line i will execute query truncate.
break; //break after saving once, for instance, and run again when the time close... This is to prevent possible multiple executions...
}
System.Threading.Thread.Sleep(500); //read 2. and 3. check every 500 millisecond, at least to give chance to check the time twice per second
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
When you run your program, it looks on the clock quickly, and if it is not exactly midnight immediately exits. (To be more precise it prints some message and waits until keypress). I believe you wish to wait until midnight. If the exact timing is not that important (I mean some seconds early or late is acceptable), the simplest solution is:
static void Main(string[] args)
{
Thread.Sleep(DateTime.Today.AddDays(1) - DateTime.Now);
Console.WriteLine("It's about midnight, I go to sleep");
}
I feel like the issue is with the flow of execution of your code.
You're calling the code once and then it stops. It checks once NOW and get the current time. If the time is 12:00:00 AM, you can pass into the if statement, but you'll need to literally run this at 12:00:00 System time on the dot, which is nearly impossible.
You should consider a Windows Service or using Windows Task Manager: C# Console Application - Keep it running.
As mentioned in the other answers you shouldn't be using your app to schedule the task. It looks like you are doing a database maintenance task so the first thing I would look at is...
1) See if your database can schedule tasks. SQL Server Agent for example can schedule stored procedures (or adhoc SQL) to be run at set times and would accomplish your task if you are using that for your database. More info here.
If your database can't do this or you want to do other things other than truncate the table then...
2) try using Windows Task Scheduler
This can launch an application at set times, is easy to setup and then your application can just do the job it's mean to do (e.g. truncate the table) and not worry about the scheduling.
Related
My current solution to ask the CNC (via ThincAPI) whether or not the program has Completed is not working. It doesn't care if I change programs, once it is successful it will always report true even after changing the loaded program.
What I would like is a variable that I can reset right before firing cycle start so I can check and see if the program truly ran. Ideally I would reset this CycleComplete method that is already being used.
I think what I'm going to end up doing is writing to a macro (common) variable and setting a value, then having the GCode change that value at the very end of the GCode program. Then I will read that value to verify it changed.
Okuma.CMDATAPI.DataAPI.CProgram myCProgram;
myCProgram = new Okuma.CMDATAPI.DataAPI.CProgram();
...
case "cycle":
string cycle = myCProgram.CycleComplete().ToString();
Console.WriteLine(" Response: " + cycle);
return cycle;
You might have to check machine in Auto Mode, and running status by using
CMachine class with method
GetNCStatus ()
GetOperationMode()
In the case of schedule program, part program is loaded really fast by NC. As a result, you might always see RUNNING status.
Using CV is also a good way to ensure that program have been set/reset.
I suspect you must be using an SDF Scheduled Program and the next program is being called before your application has a chance to catch that the previous .MIN program has completed.
The CycleComplete() method will reset when a new program is selected.
If it is returning true and the program in question didn't complete, that is because the subsequent .MIN program completed.
I would suggest putting a Dwell in between the PSelect calls in the SDF to give your app time to catch that the previous .MIN has completed or not.
I have a program for a client that needs to run one set of code every 30 minutes via a scheduled task.
at 1:30 am it needs to run a separate set of code.
Both sets of code will generate a file and place it in a directory.
How do I set it up to be able to run two sets of SQL code?
I could do it getting the current date time and comparing it but that seems bulky to me.
Is there a way a schedule task can run a program which would pass in something to my Main(string[] args)?
Is there a correct way to do it without creating two separate apps?
Make your program accept parameters, then schedule your console app (using Windows scheduler) with the different parameters... something like:
void Main(string[] args)
{
var firstArg = args.FirstOrDefault();
if (firstArg == "option1")
{
// do stuff
}
else if (firstArg == "option2")
{
// do other stuff
}
}
In scheduler do something like:
Write to flat file your param result from the first process, or database and get it from there with the second process.. Or just have your process always running and use stopwatch to perform events every 30 minutes instead of using the task scheduler, then you can keep it in memory. You have a lot of options.
Assume I have two Quartz.net jobs that
downloads a CSV file with a delta of changes for a period (e.g. 24h) and then imports the data (called IncrementalImportJob)
downloads a CSV file with a all the records and then imports the data (called FullImportJob)
The requirement is that IncrementalImportJob at a minimum once for the period (e.g. 24h). If that window is missed, or the job didn't complete successfully, then FullImportJob should run instead. The reason is that changes for that (missed) day would not be imported. This condition is rather exceptional.
The FullImportJob requires resources (time, CPU, database, memory) to import all the data, which may impact other systems. Further, the delta of changes are often minimal or non-existent. So the goal is to favour running the IncrementalImportJob when possible.
How does one configure quartz.net to run FullImportJob if IncrementalImportJob hasn't completed successfully in a specific time period (say 24h)?
Searching the web for "quartz.net recovery" and "quartz.net misfire" doesn't reveal whether its supported or whether its even possible.
There is native misfire handling in quartz.net, however it only goes as far as specifying whether the job should fire immediately again, or after a period of time or a number of times after misfiring.
I think one option is to handle this internally from IncrementalImportJob.
try
{
//download data
//import data
}
catch (Exception e) //something went wrong
{
//log the error
UpdateFullImportJobTrigger(sched);
}
//Reschedule FullImportJob to run at a time of your choosing.
public void UpdateFullImportJobTrigger(IScheduler sched)
{
Trigger oldTrigger = sched.getTrigger(triggerKey("oldTrigger", "group1");
TriggerBuilder tb = oldTrigger.getTriggerBuilder();
//if you want it to run based on a schedule use this:
Trigger newTrigger = tb.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(10)
.build();
sched.rescheduleJob(oldTrigger.getKey(), newTrigger);
//or use simple trigger if you want it to run immediately and only once so that
//it runs again on schedule the next time.
}
This is one way of doing it. Another would be abstracting this logic to a maintenance job that checks the logs every so often and if it finds a failure message from IncrementalImportJob, it fires FullImportJob. However, this depends to some extent on your logging system (most people use NLog or log4net).
If on the other hand, your concern is that the job never ran in the first place because, for instance, the app/database/server was down, you could schedule FullImportJob to fire a few hours later and check if IncrementalImportJob has fired as follows:
//this is done from FullImportJob
//how you retrieve triggerKey will depend on whether
//you are using RAMJobStore or ADO.NET JobStore
public void Execute(IJobExecutionContext context)
{
ITrigger incImportJobTrigger = context.Scheduler.GetTrigger(triggerKey);
//if the job has been rescheduled with a new time quartz will set this to null
if (!incImportJobTrigger.GetPreviousFireTimeUtc().HasValue) return;
DateTimeOffset utcTime = incImportJobTrigger.GetPreviousFireTimeUtc().Value;
DateTime previousTireTime = utcTime.LocalDateTime;
if (previousTireTime.Day == DateTime.Now.Day) return;
//IncrementalImportJob has not ran today, let's run FullImportJob
}
Hope this helps.
When using System.Threading.Thread.Sleep(n), I understand that it blocks the thread of the program, which result in the program being inaccessible; eg: Not being able to click buttons, or bring up other forms.
So what my question is, is there any other alternative that I could use that would just pause my one method, but still allow me to use buttons, and open other forms and such?
The code that I am using is messy becuase I have been using System.Threading.Thread.Sleep(1500) but here it is:
while(Reader.Read() != null)
{
ApplicationPort.WriteLine(line);
System.Threading.Thread.Sleep(1500);
}
Line is just a string that is bein updated earlier on the code, the rate that it updates is too fast for what I am trying to accomplish so I am trying to slow the program down by using Sleep. And ApplicationPort, is just a SerialPort
This code is not allowing me to use other object while it is sleeping, so is there an alternative to this where I can still use the rest of my program while the while just the while loop sleeps?
Run your method in separate thread, and you will be free to pause/resume as much as you want...
Take a look to the Thread class
You could use a while loop and Application.DoEvents Something like:
while(Reader.Read() != null)
{
ApplicationPort.WriteLine(line);
var endDate = DateTime.Now + TimeSpan.FromSeconds(1.5);
while (DateTime.Now() < endDate)
{
Application.DoEvents();
}
}
However this is "hacky" and you should be following ArsenMkrt's answer.
I'd consider adding a timer to your app and print the line when the timer hits. This would not tie up your app.
An example here Timer
I have a simple .exe that needs to be running continuously.
Unfortunately, sometimes it crashes unexpectedly, and there's nothing that can be done for this.
I'm thinking of like a C# program that scans the running application tree on a timer and if the process stops running it re-launches it... ? Not sure how to do that though....
Any other ideas?
It's fairly easy to do that, but the "crashes unexpectedly, and there's nothing that can be done for this" sounds highly suspect to me. Perhaps you mean the program in question is from a third party, and you need to work around problems they can't/won't fix?
In any case, there's quite a bit of sample code to do exactly what you're talking about.
The first solution would be to fix your EXE, so it does not crash. If you can not fix it now, you probably need to add exception handling, so you can catch the exception, and not close the EXE.
Second solution is to write simple guard programm that will start your simple .exe and will monitor specific process handle. It will restart your program when it closes.
easiest way is to have you program see if an instance of itself is running and exit if it is. Set up a scheduled task to run it every couple of minutes.
class Program
{
static void Main(string[] args)
{
if (IsRunning())
{
return;
}
else
{
for (int x = 0; x < 10; x++)
{
//Do Stuff
System.Threading.Thread.Sleep(1000);
}
}
}
private static bool IsRunning()
{
Process[] P = Process.GetProcessesByName( Process.GetCurrentProcess().ProcessName ) ;
return P.Count() > 1;
}
}
One trick occasionally employed by malware in days past was to have two processes that each monitor the currently running processes and restart the other process if it is terminated.
The System.Diagnostics namespace has classes which can help, particularly "Process".
For example
static Process[] Process.GetProcesses()
returns a list of all the currently running processes.
If your other process is not in this list, you just restart it with, for example
Process.Start()
Your program needs to initially start your target process itself (with Process.Start), then simply wait for it to terminate (with WaitForExit on object that is returned by Process.Start()). After that whole procedure is repeated.
This way you'd be sure that you are watching the process you are interested in, and you don't need to poll process list at all.
Process.Start() and WaitForExit() usage example.