So here's the thing i have a function and a timer that has an interval of 10ms.
void process()
{
//some heavy processing logic here
}
Now what i'm doing is that i have added this function to the timer.tick delegeate
timer1.tick += process;
When I run my program I'm getting exception that says
Multiple threads started to execute the same block and 'The instruction at some address referenced to another address.The memory could not be read'
But when I increase the interval time to 500ms, this exception is thrown after some time.
I am kind of new to c#, Is there any other efficient way of doing this without facing such an error.
You starting process every timer tick, so after a while your pc will really slow down. It is because you do not control thread numbers.Moreover I assume that they are using same resources, because you do not pass any arguments. This resources are probably not thread safe and this causes an exception
timers tick trigger after interval finish. your function in use by multiple ruinning Context . change timer interval as long as max run of your Process method and change to this ( disable timer in start function and enable after that ):
void process()
{
timer1.Enabled=false;
//some heavy processing
timer1.Enabled=true;
}
otherwise you must use semaphores.
Now i realized that in this function i had some variables that were being used by the program to run correctly , so when this function was being accessed many a times by different threads at the same time , it malfunctioned.
So i prevented this by using locks
void process()
{
lock(frameExtractor) // frame extractor is the variable where frames are stored
// then do some heavy processing
}
Related
Just now have some confusion about timer and thread, see below example, Both codes provide the same result (Do some checking every 60 seconds), so when should I use a timer and when should I use a thread to handle jobs when they're providing the same result?
Use Thread:
Thread checkJob = new Thread(checkStatus);
checkJob.Start();
protected void checkStatus()
{
//Do Checking here
Thread.Sleep(60000);
}
Use Timer:
public Form1()
{
InitializeComponent();
Timer time = new Timer();
time.Interval = 60000;
time.Tick += time_Tick;
time.Enabled = true;
}
void time_Tick(object sender, EventArgs e)
{
//Do Checking here
}
If the task that is performed periodically is very short, and will not get in the way of processing on the thread that the timer runs, then a timer is a reasonable choice.
On the other hand, if the periodic task takes a significant amount of time, and you cannot afford to have the main thread interrupted to perform it, then a separate dedicated thread is a good choice.
It depends on the timer you're using. If you're using a WinForms timer then your callback will fire on the gui thread. If you've got a lot of work to do then this will cause your application to block until you've finished, which will make for a bad user experience.
If you're using one of the other timers then they'll fire on a thread in the thread pool. Even here you'll want to avoid doing anything to long, but it won't block your gui thread. However, you're need to ensure you marshal any calls into the gui using the BeginInvoke method.
Starting your own thread is good if you're got long running tasks to do every time the timer fires, but once again you'll want to marshal calls back to the gui thread. Rather than using Thread.Sleep it's better to use an Event so that you can detect when the rest of the system is shutting down:
ManualResetEvent stopEvent = new ManualResetEvent(false);
Thread checkJob = new Thread(checkStatus);
checkJob.Start();
protected void checkStatus()
{
//Do Checking here
while(stopEvent.Wait(60000) == false)
{
// Do processing
}
}
Now you can stop the thread by calling stopEvent.Set()
You can view a thread as a "sub-process"; a process can have multiple threads, allowing it to perform several operations in parallel. A thread is an expensive system resource; it uses a CPU when it's active, and allocates its own call stack (1MB by default). Using a thread to perform periodic actions is a waste of precious resources, and doesn't scale well.
A timer, in the other hand, is much cheaper. It's just a time-controlled trigger that does nothing most of the time, except when it's time to execute your code. It's the right choice in your case.
I would recommend to use Timer - it is more suitable when it comes to resource consumption.
Setting up a new thread is quite expansive.
By the way in case you would like to use Thread you should set it to IsBackground=true, so that it can finish its execution when the application is shutdown.
I'm writing a windows service to execute some method every x minutes, but I want the method to execute synchronously relative to the timer itself. The windows service have a Timer object (System.Timers.Timer) which starts and calls some method 'DoWork' every x minutes, but the timer must 'stop' while 'DoWork' is executing and starts again after the method is finished.
I'm aware that using the System.Windows.Forms.Timer class would give me the behavior I want, but I don't want to add a System.Windows.Forms dll reference to my Service project.
Here is an example of 'working' code:
private System.Timers.Timer timer1;
public void MainMethod()
{
timer1 = new System.Timers.Timer();
timer1.Interval = 1000;
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
timer1.Start();
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
timer1.Stop();
DoWork();
timer1.Start();
}
private void DoWork()
{
Thread.Sleep(2000);
Console.WriteLine("found!");
}
Running above in a console application (as a mockup before writing the windows service), the expected behavior should be for the console to write 'found!' every 3 seconds.
Just a side-note: I'm just using 'Thread.Sleep(2000)' to mimic a delay but it won't form part of the actual code base.
Is there any other / "better" way to achieve this than my way above?
Thanks for reading my question and any input would be greatly appreciated.
You can't use System.Forms.Timer in a windows service because that would require a message pump and Windows services are not given a message pump stack that can be very large (plus you'd have to call Application.Run to start one).
The way you have it now is the way I implement periodic events. I'd add something to monitor whether your events take longer than the period; but other than that...
I think it depends on whether you just want the X second delay between calls to the method to be a constant, or if you'd like the method to be called every X seconds, but with allowances if the method takes longer than X seconds to execute.
Your code above will do the former, where there's a one second delay between method calls, but if you want your method to be called every X seconds, you may want to consider using timestamps with DateTime.Now and DateTime.Subtract to see if a suitable time has passed since the last method call. This may cause unusual behaviour if the system clock gets changed, such as at daylight saving time where the method may not run for an hour but this unusual behaviour may be deemed acceptable to you in your situation.
It seems that the main problem you are having is described as " the timer must 'stop' while 'DoWork' is executing and starts again after the method is finished" .In short, the service needs to be multi-threaded. You should consider using a thread pool. Using a thread pool will allow your executing thread to continue counting time will a background thread does some other work. Check out the ThreadPool docs here: http://msdn.microsoft.com/en-us/library/3dasc8as%28v=vs.80%29.aspx .
I am going to create a system service in C#.
In the onstart section I would like to loop every 30 seconds and query a mysql database. If numrows are greater than 0 I will process some faxes using the faxcom library.
My question is: Would looping every 30 seconds exhaust the program/computer? What would be the best function/method to use for the loop and sleep? Do you have any example code for the loop and sleep?
Using Thread.Sleep() would be a bad solution, because even while sleeping your thread is active. Use Timer class instead and handle its Elapsed event.
This article examines different ways to tackle the periodical execution of your service.
Here is what your OnStart method might look like:
using System.Timers;
private timer = new Timer();
protected override void OnStart(string[] args)
{
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 30000; // every 30 seconds
timer.Enabled = true;
}
Private void OnElapsedTime(object source, ElapsedEventArgs e)
{
// Execute your code here
}
I wouldn't use looping constructs for such a thing.
I would use one of the timer controls in the BCL and set it to fire every 30 seconds.
As for the question of if this is "too much", the answer entirely depends on the amount of work being done and the load it generates.
No, you would not be using the CPU, because sleeping threads are not scheduled for execution until their sleep time expires. Use Thread.Sleep to make the current thread sleep for timeout miliseconds. Something like:
while(!stop) // boolean variable to indicate when to stop the service.
{
Thread.Sleep(30000);
// do work
}
You will, of course, need to run this on a separate thread, otherwise you will block the main thread.
I would avoid using System.Timers.Timer in your case solely because you are writing a Windows Service. While you can use it, you won't have a GUI available and therefore don't need anything that this timer would expose as if you were using a GUI (it inherits from System.ComponentModel.Component for this reason). It's pretty simple
to use.
Im experimenting with the following code
private void timer1_Tick(object sender, EventArgs e)
{
Thread nT = new Thread(new ThreadStart (checkThread));
nT.Start();
}
The cheackThread() function carries out a web-request and the timer's tick property is 2000ms. All objects in the checkThread() are disposed of after use. When the program is run for long periods e.g 3 hours the OS complains about low resources. I notices that in ctrl-alt-delete the handle count is increasing when the app runs. Does the thread not release its memory automatically once it has executed all its code or is this one of those times gc.collect is permitted?
the timer's tick property is 2ms
First, your timer will not honor this. The resolution is ~20 ms.
But even 20 ms is not very long for a Webrequest. If your checkThread exceeds 20ms (every now and then) then you would be starting Threads quicker than they can finish. And so they pile up. The fact that it takes a few hours makes me think this is the most likely cause.
You could use a debugger, or a simple counter activeThreads (use Interlocked) to diagnose this.
Using the ThreadPool or the TPL (Fx4) would solve some of your issues but you would still need to check and limit the number of simultaneous requests.
You should let the Framework handle the threads, instead of using Thread go for ThreadPool.QueueUserWorkItem
I'm hoping someone can shed some light on what might be happening for me. Here's a summary of whats happening.
I have an application that does lots of "stuff". Its a pretty hefty application that does lots of number crunching using many threads. There are several timers that are used. Over a long period of time, the timers stop consistently invoking the elapsed handler.
For instance: I have a timer set to elapse every second. After a period of hours the timer starts randomly triggering late. If I do not restart the application the performance just degrades and the timers fire later and later eventually turning into 3 or 4 seconds, forcing me to restart the application. I have not been able to identify any leaks. CPU usage does not go up, memory does not go up, and the server is no where near being maxed out. Can anyone give me some ideas as to what may be causing this?
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if (seconds > 0)
{
seconds--;
timer.Start();
}
}
Is it possible you're exhausting the thread pool? Most timers invoke the handler using a threadpool thread. If all threadpool threads are in use, it will just get queued until one is available.
If that's the case switch some of your processing to use your own threads, not threadpool threads.
To test if you're exhausting the thread pool start up a background thread that periodically (a few times a second) checks ThreadPool.GetAvailableThreads and logs a message when the available is small (even if it's never actually zero when you check, if it sometimes approaches zero then it's likely this is the problem).
The size of the pool can be changed with ThreadPool.SetMaxThreads although that may not be the best solution. If you're using threadpool threads for longer running tasks, stop it. For long-running tasks use your own threads.
the timer class you use is really important
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
but I don't think the problem is the timer itself,
for instance try making an application using the same timer class
that ONLY writes the current DateTime to a log file
and leave it running for an extremely long period of time, you'll see that there's no such a 3/4 seconds delay
review your timer code and check that no shared resources are being accessed at the same time,
maybe the Timer is OK, but there's a bottleneck in the event handler function or in "something" that function uses
Sounds like maybe it's not really the same timer, and so the resources being "leaked" here are GDI handles.
Possible workaround:
DateTime mayContinue = DateTime.MinValue;
bool blockingUi = false;
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if( blockingUi )
{
if( DateTime.Now < mayContinue )
{
// Notify time remaining
// Update the UI with a BeginInvoke
}
else
{
blockingUi = false;
// Notify ready
// Update the UI with a BeginInvoke
}
}
}
private void BlockUi()
{
mayContinue = DateTime.Now.AddSeconds(30);
blockingUi = true;
}