I am having a problem getting the main Form in my program to run as I want. I am using C#. On my initial main form (Form1) I have a command button that runs a long program. In the middle of the program I want the user to be able go back to the initial form and click on some new checkboxes that I will place on that initial form from within the C# program. The code below just freezes the initial form. I do not need to get the code below to work exactly. I just need it to allow me to access the main initial form in the middle of the program that I started with the command button.
To do this I have an infinite while loop that calls the timer. Is this the correct way to do this? I do not need the program below to work. I just need to be able to access that initial Form in the middle of the program. Since it is not working it seems that it is not the way to do this but what is the correct way?
The following code runs the OnTimedEvent function (method) below. The function used to put up a Messagebox but I commented that out. I do NOT need that function to work. It is only there for testing purposes. My goal is that I need the initial main Form to allow me to enter more information while it is running from the command button. The function below runs about 15 times and I get the error
Exception of type 'System.OutOfMemoryException' was thrown.
on the line aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
The code is below:
System.Timers.Timer aTimer;
// Create a timer with a one second interval.
aTimer = new System.Timers.Timer(100);
while (true)
{
// Hook up the event handler for the Elapsed event.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false;
aTimer.Enabled = true; // uncommented this now
//addded below
aTimer.Start();
}
I have tried it in several different ways but the main Form always just freezes. I just want to be able to select things (checkboxes, for instance) on the main Form (Form1) so the below code may not be needed. The timer above calls OnTimedEvent which is below.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// MessageBox.Show("Hello World");
}
In many places on the web I have seen (including stackoverflow) that I should be using timers to get the main initial Form to be useable but the code above just causes the Form to be Frozen and I get the bar at the top of the form indicating that it is Not Responding.
I am using Windows XP and Visual Studio 2008. As I indicated above I am using C#.
To summarize, is the above code the correct way to get the main, Initial form to be available after a command button has been running? If it is, what am I doing wrong? If this is not the correct way, what is?
BTW, I asked a completely unrelated question about this project here
Any ideas?
You should simply remove the while loop
System.Timers.Timer aTimer;
// Create a timer with a one second interval.
aTimer = new System.Timers.Timer(1000);
// Hook up the event handler for the Elapsed event.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false;
aTimer.Enabled = true; // uncommented this now
//addded below
aTimer.Start();
Timer runs on a separate Thread when you start it. Your while loop just keeps starting the timer over and over again.
System.Timers.Timer
To do this I have an infinite while loop that calls the timer. Is this the correct way to do this?
No. The while loop blocks the UI thread, which in turn makes the program freeze. There's no reason to have the while loop as you're already using a timer to trigger the event.
Without seeing your full, actual, code it's hard to say, but the tradtional method of doing a long-running process without locking the UI is to use Threading in C#.
Can you do your long running action in its own thread so that you don't lock up the UI thread?
Here's a tutorial: http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
Don't use a while loop. If you want to run your OnTimedEvent method once a second, use something more like this:
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Interval = 1000; // 1000 ms is one second
myTimer.Enabled = true;
myTimer.Start();
Related
I have multiple timers running on my windows app. Each timer_tick runs a code. Right now I am working on two processes.
private async void tmrProcessDelay_Tick
private async void tmrAutopay_Tick
Just recently added the tmrAutopay as an added process so that instead of sequential process, I made them work at the same time. The problem I am having is that I am not able to restart the process of the Autopay.
Timers are declared at the top as an instance when form loads.
private System.Windows.Forms.Timer tmrProcessDelay = new System.Windows.Forms.Timer();
private System.Windows.Forms.Timer tmrAutopay = new System.Windows.Forms.Timer();
tmrAutopay.Interval = 2000;
tmrAutopay.Enabled = false;
tmrAutopay.Tick += new EventHandler(tmrAutopay_Tick);
private async void tmrAutopay_Tick(object sender, EventArgs e)
{
messagebox("tick"); // correcting this one
txtNotes.AppendText("tick");
tmrAutopay.Enabled = false;
// do some code
tmrAutopay.Enabled = true;
}
EDIT: as per Michael Randall suggestion, I tried adding break point at the top. I got the issue. Just on the logic. I just thought that it doesn't start again because "tick" only appends once, so I assumed it only ran once. When I went adding the break point, it ticked again, but for some reason, it did not appendText, reason I did assume things. Going back to the problem, due to the existing logic, after
called tick one - appendtext
enabled = true - ticked but did not append
due to logic, it did not go to enabled = true again
The timer tick only runs after I enabled it the first time, then when its ticks, I set it to false to do some code then start it again after finishing.
I have yet to try this system timer solution, and also saw some post that timers won't run on background process, since I can run it one time, it means it can.. But I just wanna ask before I change timers if there are any reasons why I am having this issue?
if you want to make like background process then you can do window service application and implement more than one timer in that code. I had good working experience with this type of application and I am confident that it will work without any issue with multiple timers. the only thing you need to be careful in code is that in case if some code takes longer than expected and more than timer interval then it will start another thread which could end up as deadlock for that timer or crash the application. Each timer works independently and creates a new thread each time when it ticks.
How to schedule the event, for instance I need to call a method which should perform its action for every given seconds. I'm developing simple windows form app, I tried using like
while(true)
{
methodToBeScheduled();
Thread.Sleep(60000);
}
This particular piece of code makes my application "Not-responding" while its executing. I hope timer can do this or any other logic that you experts suggest, kindly please let me know.
Thanks!
You can use the WinForms timer:
Timer _timer;
// In constructor (or anywhere you want to start the timer, e.g. a button event):
_timer = new Timer();
_timer.Interval = 60000; // milliseconds
_timer.Tick += (sender, e) => methodToBeScheduled();
_timer.Start();
This will cause methodToBeScheduled to be called once every 60 seconds, roughly. It will be called on the main UI thread, so avoid doing any heavy processing in it.
The advantage of using this timer is that it's built-in, doesn't require thread synchronization, and is simple to use. The disadvantage is that the interval is not exact -- the actual interval will vary depending on what other messages need to be processed in the application, and is also at the mercy of the Windows system clock, which is only accurate to 10-20ms or so.
You can use a Timer(System.Threading.Timer).
using System;
using System.Threading;
Timer _timer = null;
_timer = new Timer(o =>
{
methodToBeScheduled();
});
_timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(60));
Var sequence = Observable.interval(1).publish
Sequence.subscribe ....
Will allow to subscribe to an observable that will fire an onnext every second. See reactive extension ..
Hate typing on iPads....
Yes, there are three different types of timers (all of which are named Timer but behave a little different) in .net. The windows.forms timer executes a function at a certain rate--it calls the function from the UI thread. The System.Threading Timer does the same but calls the function from another thread. There is another timer that I can't remember off the top of my head. You will have to pick one of them based on your circumstance.
Threading timer is my favorite. Here is an example if how to use it. Just keep in mind whatever you are calling is not done from the UI thread. May want to use the forms timer or synchronize things if that's an issue.
I'm really struggling with this. I'm creating a winforms application in visual studio and need a background timer that ticks once every half hour - the purpose of this is to pull down updates from a server.
I have tried a couple of different approaches but they have failed, either due to poor tutorial/examples, or to my own shortcomings in C#. I think it would be a waste of time to show you what I have tried so far as it seems what I tried was pretty far off the mark.
Does anyone know of a clear and simple way of implementing an asynchronous background timer that is easily understandable by a C# newbie?
// Create a 30 min timer
timer = new System.Timers.Timer(1800000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
...
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// do stuff
}
with the usual caveats of: timer won't be hugely accurate and might need to GC.KeepAlive(timer)
See also: Why does a System.Timers.Timer survive GC but not System.Threading.Timer?
Declare member variable in your form:
System.Timers.Timer theTimer;
On form load (or whatever other time you need to start update polling), do:
theTimer = new System.Timers.Timer(1800000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();
Declare your PollUpdates member function like this:
private void PollUpdates(object sender, EventArgs e)
{
}
I think you need to know about all timer classes. See Jon's answer below.
What kind of timer are you using?
System.Windows.Forms.Timer will execute in the UI thread
System.Timers.Timer executes in a thread-pool thread unless you
specify a SynchronizingObject
System.Threading.Timer executes its callback in a thread-pool thread
In all cases, the timer itself will be asynchronous - it won't "take up" a thread until it fires.
Source: Do .NET Timers Run Asynchronously?
I got a little problem with my application.
I would like to update something on my UI every 10 seconds. I first used a DispatcherTimer for this but it will block my UI for a short time because the update method needs to load something from the web and this operation needs some time.
Now I thought about some kind of background worker and I found BackgroundTasks.
The problem with Background tasks is, as far as I understood it correctly, that they are supposed to serve as updaters even if the app is suspended. I don't need that.
I only would like to update if my app is running not if it is suspended.
Is there a good way to solve this?
Any suggestions what to use for this?
Thanks in advance!
You need two things for it:
Timer
You can update the UI in System.Timers.Timer with the 10 seconds interval.
Dispatcher
You need to use Dispatcher.Invoke to change the UI without holding the main UI thread. Instead the method Process should be called on a separate thread (Timer method), other than main UI thread, and use Dispatcher in it to alert main UI thread for the change.
Process() // method to be called after regular interval in Timer
{
// lengthy process, i.e. data fetching and processing etc.
// here comes the UI update part
Dispatcher.Invoke((Action)delegate() { /* update UI */ });
}
You need to create a thread that runs the part of your code that gets and processes the information from the website. This way, your form will not hesitate because it will be on a different thread than the processing part.
This Article on code-project should get you started.
Also, you could start a timer, which has a elapsed event, that occurs every time the timer passes a certain time cycle.
http://www.dotnetperls.com/timer
The other answers are missing proper cleanup: When the timer fires in the exact moment that the window was closed, I would get an uncaught TaskCanceledException when trying to run Dispatcher.Invoke. I didn't find help for this problem in other questions. I was able to solve it by unregistering the timer callback when closing the window.
public partial class MainWindow : Window
{
Timer clockTimer = null;
public MainWindow()
{
clockTimer = new Timer(1.0); // 1 ms update to test for TaskCanceledException
clockTimer.Elapsed += Timer_Elapsed;
clockTimer.AutoReset = true;
clockTimer.Start();
Closed += (object sender, EventArgs e) => { clockTimer.Elapsed -= Timer_Elapsed; };
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e) {
var now = DateTime.Now;
Dispatcher.Invoke((Action)delegate () {
UpdateTime(now);
});
}
}
Obviously this is not a good idea if the window was re-shown. I tried adding a dtor, but it would never get called, probably due to cyclic dependencies.
Disclaimer: I don't know C#, so this might not be the best or proper way of doing things.
I'm trying to use a timer in C# to run a method at an interval of five seconds. Though this code doesn't seem to work. I do not get any errrors when running it but the program (I run this in a console) shuts down right after IP.timer1.Start(). The timer1_Elapsed method is never getting executed. I know that because I've tried making the program print a string to the console at the first line of the timer1_Elapsed method.
class Program
{
Timer timer1 = new Timer();
static void Main(string[] args)
{
Program IP = new Program();
IP.timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
IP.timer1.Interval = 5000;
IP.timer1.Enabled = true;
IP.timer1.Start();
}
static void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
//Function to get executed each time the counter elapses.
}
}
The reason is that the Start method of the timer starts the timer on another thread, and immediately returns from the method. This causes your Main method to end, and the console to shut down.
Depending on what Timer you are using (there are a few similarly named classes in the BCL) you may want to implement the fix differently. I suggest reading the documentation on System.Timers.Timer, System.Windows.Forms.Timer or System.Threading.Timer depending on which it is you are using.
Your program will exit the moment the main function terminates.
You need to prevent main from exiting until you are ready, possibly with a Console.ReadLine();
The timer starts on another thread, Use the following to suspend the thread until the user hits a key after the timer start.
Console.ReadLine();
The reason that the program exits right after IP.timer1.Start() is that it is done executing the Main()-function and there is nothing stopping it from returning.
If you want a simple way to keep your program running you can add Console.ReadKey(); after timer1.Start(); so that your application will wait until that function returns (which is when you press any key). After doing this your callback should be called every five seconds as specified.