I looking to run a method periodically but would like to optimise my code by having it run in a separate thread. So far my code looks something like below:
private System.Timers.Timer timerQuartSec = new System.Timers.Timer(250);
private Thread quarterSecThread;
timerQuartSec.Elapsed += new System.Timers.ElapsedEventHandler(someMethod);
quarterSecThread = new Thread(new ThreadStart(timerQuartSec.Start));
My question is, would this code simply start the timer or would the code (on TimerElapsed) run on the new Thread?
System.Timers.Timer will run on a ThreadPool thread as long as you don't set the timer's SynchronizingObject.
So there's no need to start a dedicated thread. You need to pay attention though if you want to access GUI elements.
Related
I am facing a issue when used to system.timers.time, i have a running process in my application.
with timer called my process start, but i want to use that process within the thread only.
because every time timer elapsed event called the new thread has been generated, but i want to prevent this and only using single thread in a process.
Here is my code.
Public void Watcher()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 3000;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
}
Public void OnTimedEvent
{
// process code here
}
Here, after every 3 seconds OnTimedEvent called and new thread created, but i don't want to create new thread every time.
So, how to prevent this, any idea?
If you have a UI you should simply use forms timer or dispatch timer. If you do not have a UI you can set the SynchronizationObject of the timer. This will be responsible for marshaling the execution to the right thread.
I would probably skip the synchronization object, and just do the marshaling in the event handler of the event.
In either case you will need some kind of message loop if you do not have a UI. This would have a threadsafe queue where the thread takes a message and process it, one at a time. For example, using a blocking collection of Action.
As mentioned by #MindSwipe in the comments. A new thread will not be generated per event. It will simply take threads from the threadpool. So the number of threads used should be fairly constant. The main reason for moving all execution to one thread is because it can make threadsafety easier to manage.
I want to wait for x hours before executing some code in C#. i thought using a timer would be a good idea. (using thread.sleep does not seem right). But it just does not work. i am using the following code:
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = x * 3600000;
timer.Enabled = true;
timer.Elapsed += (o, e) => SomeFunction(username);
timer.AutoReset = true;
timer.Start();
}
this code supposed to wait for x hours and then execute SomeFunction but when i debug it, the main function ends after timer.start().
do you see any problem here? or can you suggest an alternative besides thread.sleep or await Task.Delay() ?
As soon as your Main function exits, your process ends, along with any background threads including timers.
You need to keep your main thread alive using Thread.Sleep(), Console.ReadKey() or whatever seems appropriate.
Alternatively, if you don't want to keep your process alive, you can register a scheduled task with Windows to be run in an hour's time, and then end.
There are two problems here. The first is that an executable will exit when all foreground threads are finished running. The only foreground thread is that going through Main() so it will then exit.
The second is that you aren't storing timer anywhere. Even if another thread was keeping the executable going, timer is eligible for garbage collection perhaps as soon as timer.Start() returns and certainly after Main() exits.
using thread.sleep does not seem right
It generally isn't a good idea, but considering that you only have one thread anyway, and considering that you have to have at least one foreground thread in an application, Thread.Sleep seems perfectly reasonable in this particular case. Task.Delay just as much.
More generally, I think I would prefer this to be either a scheduled task or a service. In particular, in cases where I want to wait hours before something is done, I very often want this to survive reboots.
Check out Quartz.Net and this for scheduled tasks.
I'm starting a Thread that runs routine tasks with some Files, unfortunately, calling Thread.Sleep inside that thread callback hangs up Windows for the specified time, ie. my cursor freezes and CTRL+ALT+DEL does nothing either. How do I specifically "Sleep" the background thread without hanging up the UI?
I'm creating the thread using this:
createThread = new Thread(new ThreadStart(this.createFileExec));
createThread.Start();
And my callback is like this:
private void createFileExec() {
....
Thread.Sleep(100);
....
}
How do I specifically "Sleep" the background thread without hanging up the UI?
That's exactly what you are doing by calling Thread.Sleep on your new thread. Are you sure you aren't calling createFileExec from the main thread?
James is right, there is no reason for the UI to hang .
A quick hack that you can try is to use loops instead of Thread.Sleep .
for (int i = 1; i <= 10000; i++)
{
Console.WriteLine("."); //To know that the thread is asleep.
}
I read about using BackgroundWorker class to implement thread in Windows Form application. I have a small question: If I want 5 threads being running at the same time to handle specified tasks, I must create 5 BackgroundWorker controls or just need one?
If you're talking just BackgroundWorker, then you'd have to create 5 backgrounds workers. If you simply want 5 threads, you can create those yourself. The issue then becomes how to communicate progress and completion back to the UI thread. With BackgroundWorker, you do that with WorkerReportsProgress/ReportProgress and the Completed event. Now, you could certain just uses the BackgroundWorker DoWork handler to spawn the threads you want and manage communication of data from those threads back to the UI thread via ReportProgress and Completed.
For example:
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Thread thread1 = new Thread(ThreadOneEntry);
thread1.Start();
Thread thread2 = new Thread(ThreadTwoEntry);
thread2.Start();
Thread thread3 = new Thread(ThreadThreeEntry);
thread3.Start();
Thread thread4 = new Thread(ThreadFourEntry);
thread4.Start();
Thread thread5 = new Thread(ThreadFiveEntry);
thread5.Start();
thread1.Join();
thread2.Join();
thread3.Join();
thread4.Join();
thread5.Join();
// do something to report results from threads1-5
}
This, of course, doesn't do anything with progress--that would be very application specific and anything I come up with is likely to be entirely different than what you would do and be of no help. But, each thread could report progress back through the BackgroundWorker.ReportProgress method directly--you'd just have to give each thread the BackgroundWorker instances or a delegate to the ReportProgress method.
it's also not a terribly effective use of a thread for the background worker, it just goes into a wait state waiting for other threads, the DoWork event handler could just as easily do some of the work that one of the other thread entries would have...
I'd recommend using Task<T> instead of Thread if you are on .NET 3.5 or better and you want to perform background work that has results. Plus, spinning up your own threads does no load-balancing. Task through the TPL does its own load balancing...
A BackgroundWorker is basically a single thread, so you would need multiple instances if you needed to run more than one thread.
In my WPF application i use 3 different DispatcherTimers.
One is for displaying the current time
One is are for running a DB query every 5 sec
The third one refreshes a value for a custom button every 1 sec
When my program is running there are a lot of delays / freezes.
For example the time starts ticking correctly but on a sudden the value freezes up and after the freeze the time gets incremented by +3 seconds for example.
I am getting this behavior over my entire application.
What is the proper way to solve this problem with several timers?
EDIT:
I am having problems to replace a DispatcherTimer with a Timer from System.Timers namespace.
//new code with timer
timerW = new Timer();
timerW.Elapsed += new ElapsedEventHandler(timerWegingen_Tick);
timerW.Interval = 5000;
timerW.Start();
//OLD Working Code
timerW = new DispatcherTimer();
timerW.Tick += new EventHandler(timerWegingen_Tick);
timerW.Interval = new TimeSpan(0, 0,5);
timerW.Start();
Error : "The calling thread must be STA, because many UI components require this."
Best regards.
the DispatcherTimer is executed on the UI thread. So if the UI thread is busy for more than the interval, it will be executed when the UI thread is free to do so.
If you need more precise scheduling, you should go for a time than runs in the background (System.Threading.Timer, System.Timers.Timer). But don't forget about marshalling then.
hth,
Martin
I guess this is because they all are running on same thread.
Use System.Threading.Timer and when updating UI use the SyncronizationContext.Syncronize to run the updating code in.
Don't forget to get the context from SyncronizationContext.Current on the UI thread.