I'm pretty new in c# and I'm programing just for my personal studies, I have been trying to program an instruction where a read some data from a remote station to my application (m64...mw74), it's running OK for couple minutes but its crash maybe after 5 minutes.
please see the code I'm using below to update my data every 1 second and write it in a simple text box in my form.enter image description here
Thank you very much in advance.
private void Load_act()
{
actvalueL1.Text = plc.Read("mw64").ToString();
actvaluep1.Text = plc.Read("mw68").ToString();
actvaluep2.Text = plc.Read("mw71").ToString();
actvaluep3.Text = plc.Read("mw74").ToString();
InitTimer();
}
private Timer timer1;
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000; // in miliseconds
timer1.Start();
//Console.ReadLine();
}
private void timer1_Tick(object sender, EventArgs e)
{
Load_act();
}
You're chaining the timers, eventually going to run yourself out of memory as they cannot dispose - the timer creates the next with its own call. Return them on to a parent method that loops your timer 'initTimer'
Related
I have a little problem. There is something like chess timer. When i press button, current timer stops and second starts, but after 1 second. How can i start second one immediately?
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
public partial class Form1 : Form {
byte sec1;
byte sec2;
public Form1() {
InitializeComponent();
sec1 = 0;
sec2 = 0;
}
private void button1_Click(object sender , EventArgs e) {
timer1.Start();
timer2.Stop();
}
private void button2_Click(object sender , EventArgs e) {
timer2.Start();
timer1.Stop();
}
private void timer1_Tick(object sender , EventArgs e) {
label1.Text = sec1.ToString();
sec1++;
}
private void timer2_Tick(object sender , EventArgs e) {
label2.Text = sec2.ToString();
sec2++;
}
}
}
Edit
I know your question is "how to start the timers immediately", but in your code they are starting immediately. When you call start the timer starts. I believe the effect you are seeing is related to the delay associated with the tick event, which from the description I am assuming is set to a 1 second interval. Since you have said that you are trying to simulate something similar to a chess timer (although in your case counting up as opposed to down), then using something like a stop watch which can start, stop and show elapsed time would be a closer model. Since there is a Stopwatch class that provides exactly this behavior, I think it would be easier to implement it using two of those and just have a single background thread that updates the UI as frequently as needed. You could even add an update call into each button push to ensure the text boxes are up to date.
===============================
Maybe instead of the timers you should use two instances of the Stopwatch class. This will remove the need for your two variables that you are using to keep track of the seconds as the Stopwatch class will be holding the elapsed time for each counter.
Then in your button methods you could just do this:
private Stopwatch sw1 = new Stopwatch();
private Stopwatch sw2 = new Stopwatch();
private void button1_Click(object sender , EventArgs e) {
sw1.Start();
sw2.Stop();
}
private void button2_Click(object sender , EventArgs e) {
sw2.Start();
sw1.Stop();
}
And then you can use a Background worker or some other background thread that runs and updates your text boxes with the elapsed time from the timers you just need to grab the elapsed time.
// This will give you the total number of seconds elapsed.
var timer1Seconds = Math.Floor(sw1.Elapsed.TotalSeconds);
Here is an example of how you can make this update the UI:
private bool _stop = false;
public Form1()
{
InitializeComponent();
Task.Run(() =>
{
while(!_stop)
{
UpdateElapsedTimes();
Thread.Sleep(1000);
}
}
}
private void UpdateElapsedTimes()
{
if (InvokeRequired)
{
Invoke(UpdateElapsedTimes());
return;
}
label1.Text = Math.Floor(sw1.Elapsed.TotalSeconds).ToString();
label2.Text = Math.Floor(sw2.Elapsed.TotalSeconds).ToString();
}
Note - in a production program I would not use a boolean as my loop checker, you would use an event handle, and probably a couple of event handles if you wanted to allow pausing the updates, this is just to show an idea of how to do it. You could invoke directly from the thread method and drop the InvokeRequired check, but I added that for additional safety and since it was there I skipped it in the loop.
The timer does start immediately. The problem is that you are not reporting fractions of seconds, so the display will show 0 until a full second has elapsed, which is accurate, technically.
If you want to show 1 immediately, just initialize your variables that way.
public Form1() {
InitializeComponent();
sec1 = 1;
sec2 = 1;
}
This is my second question on StackOverflow here. I posted my first question a while ago and got a working reply in no time, much impressed, much appreciated.
Anyways, so what I want to know is, how to get a DispatcherTimer to work and show time in a certain textbox and stop it when it reaches a certain time (let's say 60 seconds) and perform a function after 60 seconds.
What I'm basically using this for is :
Making a game, which has to stop after 60 seconds and show the scores or related stuff. So this requires me to show the time in a textbox and perform a function at 60 seconds or after that.
Here's more information :
Textbox is called "timerbox"
Here's the code I've tried :
DispatcherTimer dt = new DispatcherTimer();
private void TimerStart(object sender, RoutedEventArgs e)
{
dt.Interval = TimeSpan.FromSeconds(1);
dt.Tick += dt_Tick;
dt.Start();
}
int count = 0;
void dt_Tick(object sender, object e)
{
count = count + 1;
timerbox.Text = Convert.ToString(count);
}
It doesn't show the time in textbox, plus I don't know how to make it stop at certain point and perform a function.
Thank you for reaching here, please leave answers with full explanation as I'm a complete beginner :)
P.S. I'm using Windows Store App Development Environment in Visual Studio 2013.
And there's no "Timer" in it as there is in normal C# Environment.
AOA.
I am recently started learning c#. (interested in windows form application). Hope this help you.
if you just want to set timer for a curtain event.....
recommend you using timer ( in toolbox )......
follow steps, when you double click on timer1 VS will create a timer1_Tick function for you which will be called every timer you timer ticks.....
now what you want to do when timer1 icks write it in there....like this....
private void timer1_Tick(object sender, EventArgs e)
{
//enter your code here
}
now write timer1. and VS will display a list of avaliable function....
for example,
timer1.Interval = (60*1000); //enter time in milliseconds
now when you want to start the write......
timer1.Start();
and to stop timer at any timer call
timer1.Stop();
if you want to repeat timer just write timer1.start() in that tick function.....
plus, to set textbox text equal to timer1 time use something like
textBox1.Text = Convert.ToString(timer1.Interval);
Click here for more information on timer class
hope this help you,
in case of any confusion, just comment,.....
The normal flow of a DispatcherTimer would look like this:
First Set up your new Object, set up the a new EventHandler that will run your desired code each Tick and Set the Timespan for the desired Tick Interval.
public MainPage()
{
this.InitializeComponent();
timer = new DispatcherTimer();
timer.Tick += new EventHandler<object>(timer_Tick);
timer.Interval = TimeSpan.FromMilliseconds(bpm);
}
Set The Timer_Tick Envent
async Void timer_Tick(object Sender, object e)
{
await this.Dispatcher.RunAsync(Windows.UI.core.CoreDispatcherPriority.High, () =>
{
//Run the Code
textBox1.text = timer.interval.TotalMilliseconds.ToString();
});
You have to have a trigger to Start the Dispatcher(and to stop if you need to), for example a button
private void StartButton_Click()
{
timer.Start();
}
This example was done using The new windows 10 Universal App platform within VS2015, but I think it should look about the same in a normal windows 8 App
in a company I'm working we want to build an automation tool that should run a script written in text. I'm new to timers, and what I want to do is to make a foreach (not a must) that will run line after line in the script and call a parser for later use.
What I want is something like this:
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
foreach (ScriptCell CELL in ScriptList)
{
//fire the method when time is up
aTimer.Elapsed += new ElapsedEventHandler(DoScriptCommand(CELL.CellText));
}
I know what I wrote doesnt make allot of sense , but I'm a BIT clueless here
PS. I was looking in other topics before posting this Q , but I didnt find nothing that seems to fill the gap
The introduction of await makes acting on each item in a sequence, while waiting for a period of time between each item, very easy:
foreach(var cell in ScriptList)
{
DoScriptCommand(cell.CellText)
await Task.Delay(TimeSpan.FromSeconds(2));
}
Do this IN the elapsed event, not a new handler for each line (otherwise they'll be executed in a parallel manner)
aTimer.Elapsed += new ElapsedEventHandler((sender, args) =>
{
foreach (ScriptCell CELL in ScriptList)
{
DoScriptCommand(CELL.CellText);
}
}
If you are simply looking at running a script or scripts on a regular basis I would search "cron" if you are using a Unix/Linux machine or "Windows Task Scheduler" if you are using a windows machine. Each of these tools lets you specify a path to a script, the interval they should run, what command line parameters to use etc.
I did little tetris in my application.
I used timer for this code: I hope it will help you.
İf you dont use thread, your program will stuck while timer is running
so i used thread like this:
private void ciz()
{
int beklemeSuresi = 1000;//1000 = 1sec
for (int i = 0; i < 15; i++)
{
if (g != null)
{
g.Clear(Color.AliceBlue);
}
solLCiz(100, 100 + i * 20, yon);
Application.DoEvents();
Thread.Sleep(beklemeSuresi);
}
}
Of course you must begin thread at beginning of program like this:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ciz();
}
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
I have a brief question.
In my program I want to use a ToolStripStateLabel to display some info to the user. Comming from c++ and QT I don't quite understand the .net variant of this controll. Because I want to show the user a message for a certain ammount of time I.E 3000ms. or 3 seconds but I can't seem to figure out how to do this. So, is it even possible and, how do I do this?
Unfortunately you have to implement Timer to do that.
private void InitTimer()
{
var myTimer = new Timer();
myTimer.Tick += new EventHandler(TimerEventProcessor);
// Sets the timer interval to 3 seconds.
myTimer.Interval = 3000;
myTimer.Start();
}
private static void TimerEventProcessor(object sender, EventArgs e)
{
ToolStripStatusLabel.Visible = false;
(sender as Timer).Stop();
}
I would like to slow down a loop so that it loops every 5 seconds.
In ActionScript, I would use a timer and a timer complete event to do this. How would I go about it in C#?
You can add this call inside your loop:
System.Threading.Thread.Sleep(5000); // 5,000 ms
or preferable for better readability:
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
However, if your application has a user interface you should never sleep on the foreground thread (the thread that processes the applications message loop).
You can try using Timer,
using System;
public class PortChat
{
public static System.Timers.Timer _timer;
public static void Main()
{
_timer = new System.Timers.Timer();
_timer.Interval = 5000;
_timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true;
Console.ReadKey();
}
static void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//Do Your loop
}
}
Also if your operation in loop can last more then 5 sec, You can set
_timer.AutoReset = false;
to disable next timer tick until operation finish in loop
But then end end of loop You need again to enable timer like
_timer.Enabled = true;
Don't use a loop at all. Set up a Timer object and react to its fired event. Watch out, because these events will fire on a different thread (the timer's thread from the threadpool).
Let's say you have a for-loop that you want to use for writing to a database every second. I would then create a timer that is set to a 1000 ms interval and then use the timer the same way you would use a while-loop if you want it to act like a for-loop. By creating the integer before the loop and adding to it inside it.
public patial class Form1 : From
{
timer1.Start();
int i = 0;
int howeverLongYouWantTheLoopToLast = 10;
private void timer1_Tick(object sender, EventArgs e)
{
if (i < howeverLongYouWantTheLoopToLast)
{
writeQueryMethodThatIAssumeYouHave(APathMaybe, i); // <-- Just an example, write whatever you want to loop to do here.
i++;
}
else
{
timer1.Stop();
//Maybe add a little message here telling the user the write is done.
}
}
}