Let us consider a method which changes the string contains value often .
I need to create thread which runs for every 1 min for getting a values from a string .
Is it possible?
I have tried following code which sleeps the entire process other that particular thread:
System.Threading.Thread.Sleep(10000);
If you wand to run a threaded process at a defined period of time the System.Threading.Timer class will be perfect
var timer = new System.Threading.Timer((o) =>
{
// do stuff every minute(60000ms)
}, null, 0, 60000);
However if you are updating any UI code from this thread dont forget to invoke back on the UI thread
WPF:
var timer = new System.Threading.Timer((o) =>
{
Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate
{
// do stuff WPF UI safe
});
}, null, 0, 60000);
Winform
var timer = new System.Threading.Timer((o) =>
{
base.Invoke((Action)delegate
{
// do stuff Winforms UI safe
});
}, null, 0, 60000);
Example:
private void StartUpdateTimer()
{
var timer = new System.Threading.Timer((o) =>
{
string ss = "gowtham " + DateTime.Now.ToString();
Response.Write(ss);
}, null, 0,1000);
}
Sleep does not start new thread, it blocks current thread (in your case UI thread) for given number of milliseconds.
Based on your description you want to start new thread and can sleep in that thread. Also it may be easier to use timers. Complete sample and information on Thread object avaialbe in MSDN Thread article:
new Thread(ThreadFunction).Start();
Use:
new Thread(delegate()
{
while(true)
{
// Do stuff
Thread.sleep(60000);
}
}).Start();
60 000 miliseconds is a minute
Thread.sleep puts the current thread to sleep
C# or more spesificly .NET supports MULTITHREADING.
when you use Thread.Sleep() it will disable the one thread that used Thread.Sleep()
here is an exmaple of using the 'TPL' to lunch athread that samples the string every 60 seconds
System.Threading.Tasks.Task.Factory.StartNew(
()=>
{
System.Threading.Thread.Sleep(60000);
ReadString()}
)
you should keep in mind that you need to protect your string from RACE CONDITION
use C# lock for this
Instead of starting a new thread every 60 seconds, use one thread, that sleeps after finishing until the next run. Something like this:
Class Main{
public void startObserverThread(){
Thread t = new Thread(this.observerThread);
t.start();
}
private DateTime lastRun = null;
public void observerThread(){
if (lastRun == null || DateTime.Now.Subtract(lastRun).Seconds >= 60){
lastRun = DateTime.Now;
//do thread work.
}else{
//check every second, if time elapsed
Thread.sleep(1000);
}
}
}
Change the waiting time if it needs to be more accurate.
The big advantage vs resheduling a new thread at the end of the thread is, that you dont need to take care about the execution time of the task itself. If it takes 10 seconds, the thread will sleep for like 50 seconds. if it takes 50 seconds, the thread only sleeps 10 seconds after completing the task work.
Related
I have to loop through code for specified time .I achieved it with DateTime
var time=DateTime.Now.AddMinutes((Convert.ToDouble(1)));
while(DateTime.Compare(DateTime.Now, time) <= 0)
{
console.write("some message..")
}
How do i achieve the same with Timer.Timer or thread.timer which is best approach..
Is it possible to write 10 times per sec?
Can anyone suggest. thank you
You could always use StopWatch, which is accurate and most appropriate for your scenario.
Action<long> action = (milliseconds) =>
{
Console.WriteLine("Running for {0}ms", milliseconds);
Stopwatch watch = new Stopwatch();
watch.Start();
while (watch.Elapsed.TotalMilliseconds <= milliseconds)
{
Console.WriteLine("ticks:{0}", DateTime.Now.Ticks);
Thread.Sleep(100);
}
Console.WriteLine("Done");
watch.Stop();
};
Task.Run(() => action(1000));
if you are going to make this work you need to make your program multithreaded,
See System.Threading and System.Threading.Task
Once you have your code executing in it's own thread, (using Thread, Task, Timer or any of the other variations in those namespaces) you can tell it to stop executing for a set amount of time, this is done by calling the Thread.Sleep or Task.Delay methods.
e.g.
Task.Run(()=>
{
do
{
//do something
await Task.Delay(100);
}
while(! exitCondition)
});
however you shouldn't count on this for exact timing as what you are doing is saying to the OS that this thread doesn't need to be executed for that amount of time, it doesn't mean the OS will pass it to the processor immediately on the time running out. depending on how busy the CPU is there can be quite a delay before your thread reaches the top of the waiting to process queue. if the timing is vitally important then i would set a lower time and check the clock before running
static void Main(string[] args)
{
System.Threading.Timer timer = null;
int counts = 0;
timer = new Timer((obj) =>
{
Console.WriteLine(counts);
if (++counts > 10)
timer.Dispose();
}, null, 100, 100);
for (;;) ;
}
will call the method dosomething() after 100ms, every 100ms
in the background, till timer.Dispose() is called;
this implementation will ofc never terminate as it is written here ;)
There I declared a timer (the period value of this timer is 1 minute) when the form is initialized
public Form3()
{
InitializeComponent();
timer_1m = new System.Threading.Timer(new TimerCallback(timerElapsed_test), null, 0, _1min);
}
Every 60 seconds, I start a new thread to do something.
void timerElapsed_test(object sender) //timer period: 60 seconds
{
Thread thread = new Thread(new ParameterizedThreadStart(Do));
thread.Start(null);
}
void Do(object o)
{
label1.Text = "triggerd at " + DateTime.Now.ToString("HH:mm:ss"); //assume this is a task needs to take a lot of time
//Do I need to close this thread here? and how?
}
Do I need to close the thread manually? If yes, how?
Like Idle_Mind said, once the thread "exits" you are fine.
After a thread's routine has completed, garbage collection will handle it.
I need a logic that would allow me to do something when a thread is running for more that X amount of seconds.
Like in this incredibly ugly example, here it will check every second and if the workerThread is running for 10 or more minutes it shows a message...
var timeWorking = TimeSpan.FromMinutes(0);
workerThread = new Thread(RunTask);
workerThread.Start(task);
while (workerThread.IsAlive)
{
Thread.Sleep(TimeSpan.FromSeconds(1));
timeWorking = timeWorking.Add(TimeSpan.FromSeconds(1));
if (timeWorking.TotalMinutes < 10) continue;
timeWorking = TimeSpan.FromMinutes(0);
Console.Writeline("Here we go... the event")
}
Please help me to make it right...
What should I use Diagnostics.StopWatch, System.Timers.Timer or Threading.Timer ?
UPD: All the answers confused me even more...
The task is to check if workerThread is running for more than X amount of time, and if it is, call some method, reset the timer and check again if workerThread now is running for more than X amount of time since the last time we called the method... and so on and on...
UPD2: Basically I have a thread that does a processing based on information pulled from AmazonSQS queue. SQS Queue message has a visibility timeout. If the task will take longer than default visibility timeout - the message will be back to the queue before the task has finished. And then it will be picked up by another machine. To avoid that I need to extend visibility timeout of SQS message.
So I can do that by checking periodically if thread stil isALive then I can add couple of minutes to the message visibility timeout. After a minute and 50 seconds or so, I should check again and if thread still isALive then add couple more minutes and so on.
Since you know that the thread needs to do something after ten minutes, why not simply use an interval on the timer like this:
var interval = 1000 * 60 * 10; // ten minutes
var timer = new System.Timers.Timer(interval) { AutoReset = false };
timer.Elapsed += ((sender, eventArgs) =>
{
// Do your work here...
});
workerThread = new Thread(RunTask);
workerThread.Start(task);
timer.Start();
This way you are not checking each second and you will execute your code after a desired amount of time.
I think System.Timers.Timer is better suited based on what you've described. But, it depends. If you want to do something with the UI with the timer. Forms.Timer is better.
In either case, you could simply check if the thread is still alive when the timer Elapsed (or Ticked) and do something if it is.
e.g.
timeThreadStarted = DateTime.Now;
workerThread = new Thread(RunTask);
System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
workerThread.Start(task);
//...
static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if(workerThread != null && workerThread.IsAlive)
{
Console.WriteLine("thread has been running for {0}!", DateTime.Now - timeThreadStarted);
}
}
This checks the thread state after 1 second. If it is still Alive then it has been running for at least one second.
This has the benefit of not blocking any threads. If you have a UI and you want to do this, then you can't block the UI Thread (it will become unresponsive and provide a poor user experience).
You could also do Thread.Join with a TimeSpan like the example at http://msdn.microsoft.com/en-us/library/23f7b1ct.aspx so that you don't have to do a Thread.Sleep.
Note: either approach blocks calling thread until the time has elapsed. Not suitable for main/UI threads.
You can use a Timer that will raise an event once the elapsed time as triggered.
private static void Main(string[] args)
{
var thread = new Thread(
() =>
{
var timer = new System.Timers.Timer
{
Interval = 10000, //10s
AutoReset = false, //only raise the elapsed event once
};
timer.Elapsed += timer_Elapsed;
timer.Start();
while (true)
{
Console.WriteLine("Running...");
Thread.Sleep(1000); //Always put a thread to sleep when its blocking so it does not waste CPU cycles.
}
});
thread.Start();
}
private static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//thread is running for more that X (10s) amount of seconds
Console.WriteLine("Timer elapsed");
}
That is a simple example. In this example, the thread never exits. But you can add your own logic where necessary to get what you are trying to accomplish.
Short answer: Yes, use System.Timers.Timer
You can use the Task wait method, for example
var t = Task.Factory.StartNew(() => MyAction()); // MyAction is an action to be executed in parallel
bool check = t.Wait(10000); //wait for 10000 milliseconds
if (check)
{
// all ok
}
else
{
// over time
}
The Wait method blocks until the task ends or timeout happens. If you don't want to block your primary thread, you can run the example code using another task that works in parallel and checks the working task.
I created a windows service, that is supposed to check a certain table in the db for new rows every 60 seconds. For every new row that was added, I need to do some heavy processing on the server that could sometimes take more than 60 seconds.
I created a Timer object in my service, that ticks every 60 seconds and invokes the wanted method.
Since I don't want this timer to tick while processing the new lines found, I wrapped the method in a lock { } block, so this won't be accessible by another thread.
It looks something like this :
Timer serviceTimer = new Timer();
serviceTimer.Interval = 60;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this)
{
// do some heavy processing...
}
}
Now, I'm wondering -
If my timer ticks, and finds a lot of new rows on the db, and now the processing will take more than 60 seconds, the next tick won't do any processing till the previous one finished. This is the effect I want.
But now, will the serviceTimer_Elapsed method go off immediatly once the first processing was finished, or will it wait for the timer to tick again.
What I want to happen is - if the processing requires more than 60 seconds, than the timer will notice the thread is locked, and wait another 60 seconds to check again so I will never get stuck in a situation where there are a queue of threads waiting for the previous one to finish.
How can i accomplish this result ?
What is the best practice for doing this ?
Thanks!
You might try disabling the timer during processing, something like
// Just in case someone wants to inherit your class and lock it as well ...
private static object _padlock = new object();
try
{
serviceTimer.Stop();
lock (_padlock)
{
// do some heavy processing...
}
}
finally
{
serviceTimer.Start();
}
Edit : OP didn't specify whether the reentrancy was caused only by the timer or whether the service was multi threaded. Have assumed the later, but if the former then locking should be unnecessary if the timer is stopped (AutoReset or manually)
You don't need the lock in this case. Set timer.AutoReset=false before starting it.
Restart the timer in the handler after you are done with your processing. This will ensure that the timer fires 60 seconds after each task.
A similar variation on other answers, that allows the timer to keep ticking and only do the work when the lock can be obtained, instead of stopping the timer.
Put this in the elapsed event handler:
if (Monitor.TryEnter(locker)
{
try
{
// Do your work here.
}
finally
{
Monitor.Exit(locker);
}
}
Put a quick check it see if the service is running. if it is running it will skip this event and wait for the next one to fire.
Timer serviceTimer = new Timer();
serviceTimer.Interval = 60;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();
bool isRunning = false;
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this)
{
if(isRunning)
return;
isRunning = true;
}
try
{
// do some heavy processing...
}
finally
{
isRunning = false;
}
}
I recommend you don't let the timer tick at all while its processing.
Set the Timers AutoReset to false. And start it at the end. Here's a full answer you might be interested in
Needed: A Windows Service That Executes Jobs from a Job Queue in a DB; Wanted: Example Code
Other options might be to use a BackGroundWorker class, or TheadPool.QueueUserWorkItem.
Background worker would easily give you the option check for current processing still occurring and process 1 item at a time. The ThreadPool will give you the ability to continue queueing items every tick (if necessary) to background threads.
From your description, I assume you are checking for items in a queue in a database. In this case, I would use the ThreadPool to push the work to the background, and not slow/stop your checking mechanism.
For a Service, I would really suggest you look at using the ThreadPool approach. This way, you can check for new items every 60 seconds with your timer, then Queue them up, and let .Net figure out how much to allocate to each item, and just keep pushing the items into the queue.
For Example: If you just use a timer and you have 5 new rows, which require 65 seconds of processing time total. Using the ThreadPool approach, this would be done in 65 seconds, with 5 background work items. Using the Timer approach, this will take 4+ minutes (the minute you will wait between each row), plus this may cause a back-log of other work that is queueing up.
Here is an example of how this should be done:
Timer serviceTimer = new Timer();
void startTimer()
{
serviceTimer.Interval = 60;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.AutoReset = false;
serviceTimer.Start();
}
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
// Get your rows of queued work requests
// Now Push Each Row to Background Thread Processing
foreach (Row aRow in RowsOfRequests)
{
ThreadPool.QueueUserWorkItem(
new WaitCallback(longWorkingCode),
aRow);
}
}
finally
{
// Wait Another 60 Seconds and check again
serviceTimer.Stop();
}
}
void longWorkingCode(object workObject)
{
Row workRow = workObject as Row;
if (workRow == null)
return;
// Do your Long work here on workRow
}
There's quite a neat way of solving this with Reactive Extensions. Here's the code, and you can read a fuller explanation here: http://www.zerobugbuild.com/?p=259
public static IDisposable ScheduleRecurringAction(
this IScheduler scheduler,
TimeSpan interval,
Action action)
{
return scheduler.Schedule(
interval, scheduleNext =>
{
action();
scheduleNext(interval);
});
}
And you could use it like this:
TimeSpan interval = TimeSpan.FromSeconds(5);
Action work = () => Console.WriteLine("Doing some work...");
var schedule = Scheduler.Default.ScheduleRecurringAction(interval, work);
Console.WriteLine("Press return to stop.");
Console.ReadLine();
schedule.Dispose();
another posibility would be something like this:
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (System.Threading.Monitor.IsLocked(yourLockingObject))
return;
else
lock (yourLockingObject)
// your logic
;
}
I have a Windows Service application which uses a Threading.Timer and a TimerCallback to do some processing at particular intervals. I need to lock down this processing code to only 1 thread at a time.
So for example, the service is started and the first callback is triggered and a thread is started and begins processing. This works ok as long as the processing is completed before the next callback. So say for instance the processing is taking a little longer than usual and the TimerCallback is triggered again whilst another thread is processing, I need to make that thread wait until the other thread is done.
Here's a sample of my code:
static Timer timer;
static object locker = new object();
public void Start()
{
var callback = new TimerCallback(DoSomething);
timer = new Timer(callback, null, 0, 10000);
}
public void DoSomething()
{
lock(locker)
{
// my processing code
}
}
Is this a safe way of doing this? What happens if the queue gets quite substantial? Is there a better option?
If it's OK for you to have the events fire with a constant interval between them (as opposed to the current code which fires them at a constant interval) then you can start the timer without a period, and each time queue up a new callback, e.g.
static Timer timer;
public void Start()
{
var callback = new TimerCallback(DoSomething);
timer = new Timer(callback, null, 0, Timeout.Infinite);
}
public void DoSomething()
{
try
{
// my processing code
}
finally
{
timer.Change(10000, Timeout.Infinite);
}
}
This code tells the newly created timer to fire immediately, once only. In the processing code it does the work and then tells the timer to fire again in 10 seconds, once only. Because the timer is now not firing periodically but is being re-started by its callback method then the callback is guaranteed to be single-threaded with no queue.
If you want to keep a constant interval, then it's a bit trickier as you have to decide what to do if the processing starts taking longer than the timer interval. One option is to do what you're currently doing but that will essentially end up with a lot of queued threads and eventual thread pool starvation. Another option is to simply discard the callback if there is already one in progress, e.g.
static Timer timer;
static object locker = new object();
public void Start()
{
var callback = new TimerCallback(DoSomething);
timer = new Timer(callback, null, 0, 10000);
}
public void DoSomething()
{
if (Monitor.TryEnter(locker))
{
try
{
// my processing code
}
finally
{
Monitor.Exit(locker);
}
}
}
The worst that can happen if the processing code takes more than 10s to execute is that you will be wasting 1 threadpool thread every time there's a new callback called (they will be waiting for in the lock statement). And if you take all the threadpool threads HttpWebRequest, ASP.NET, asynchronous delegate invocations... will suffer.
What I would do is to schedule the first callback immediately. Then, if you really need your DoSomething() to be called every 10s:
public void DoSomething ()
{
DateTime start = DateTime.UtcNow;
...
TimeSpan elapsed = (DateTime.UtcNow - start);
int due_in = (int) (10000 - elapsed.TotalMilliseconds);
if (due_in < 0)
due_in = 0;
timer.Change (due_in, Timeout.Infinite);
}
Or something along that line.