Remove or Replace Invoke Delegate C# - c#

Before all. I'm not so good at this and hopefully you will understand it anyway.
Im making a function in my program where it checks to see if a row in a rtb is highlighted. If not, it highlights it.
For this to work I had to use different threads to be able to access the rtb from different places. My problem is that it creates a new "delegate"/instance/thread every time the timer refreshes. I would like to remove the old thread/delegate or replace it with the new.
Because now the program crashes after a while. It's a very small program but after 40 sec i reach over 3gb ram usage.
Thanks in advance!
Haris.
Code:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();

What is happening if i am not mistaken is that you are creating and starting new timers exponentially. So your forms loads, Form1_Load method is called. Form1_Load creates a new timer that when elapsed, will call Form1_Load again. As the old timer not being disposed 2 timers are running now that will both create 2 new timers. 4 timers create 4 new so there are 8, 16, 32 and so on...
Basically what you have to do is call other method on timer elapsed:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += ATimer_Elapsed;//new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
RefreshColor();
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
Timer(); is only called ones thus creating only one timer.

Related

How to run function, when the user finished typing? (C#)

I have a text field in which the user inserts or typing text for further translation into another language. I need to run the function after the user finished typing - how to determine it?
!!! Note the order of settings for the timer
// Create a System.Timers.Timer
System.Timers.Timer aTimer = new System.Timers.Timer();
// On KeyUp, start the countdown
private void richTextBox1_KeyUp(object sender, KeyEventArgs e) {
aTimer.Interval = 1000; // time in ms (1 sec)
aTimer.AutoReset = false; // "false" - calls the event once, "true" - repeatedly
aTimer.Elapsed += OnTimeout; // event binding
aTimer.Enabled = true; // timer run
}
private void OnTimeout(object sender, ElapsedEventArgs e) {
if (InvokeRequired) Invoke(new Action(() => DoneTyping() ));
}
// User is "finished typing", do something
private void DoneTyping() {
// do something
}

System timer c#

I have some code involving a system timer that starts counting in seconds when a file is added to a folder then stops when it is removed. when the timer is stopped is shows the correct time however when I restart the timer it picks up where it left off instead of restarting at 0. Here is my code..
t2 = new System.Timers.Timer();
t2.AutoReset = true;
t2.Interval = 1000;
t2.Elapsed += OnTimeEvent2;
watch();
}
private void OnTimeEvent2(object sender, System.Timers.ElapsedEventArgs e)
{
Invoke(new Action(() =>
{
s += 1;
lblSeconds.Text = string.Format(s.ToString());
}));
}
Use the System.Windows.Forms.Timer so you don't need to worry about cross-threading. Here's a quick example of using the Stopwatch class:
private System.Windows.Forms.Timer tmr = new Timer();
private System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
private void Form1_Load(object sender, EventArgs e)
{
tmr.Interval = 1000;
tmr.Tick += Tmr_Tick;
tmr.Start();
sw.Start();
}
private void Tmr_Tick(object sender, EventArgs e)
{
lblSeconds.Text = ((int)sw.Elapsed.TotalSeconds).ToString();
}
To make the timer start from zero again, simply use the Restart() method:
private void button1_Click(object sender, EventArgs e)
{
sw.Restart();
}
I would recommend using DispatcherTimer instead. That way you don't need to invoke on the GUI thread manually. Also, it will reset on Stop/Start.
You might want to do something else to prevent many timers from running:
When a file is created register the DateTime somewhere and put a filesystemwatcher on the file.
..then on the watchers deleted event get the DateTime once more and compare them.
In fact, if you're just monitoring a folder for the appearance adn disappearance of a specific file the filesystemwatcher can help you detect both events.
Else remember to reste your counter manually when you detect the file deletion.

Change button color for a short period of time from its last click c# WPF

I used this link in order to solve my problem, but with a partial success
Change button color for a short time
I need to Present a red button.
Whenever the button is clicked, it changes its color to green for a period of 5 second,
Consecutive clicks should be supported but should not accumulate i.e. the button color should turn back to red 5 second after the last click.
my code:
private void myButton_Click(object sender, RoutedEventArgs e)
{
Timer timer = new Timer { Interval = 5000 };
timer.Elapsed += HandleTimerTick;
myButton.Background = new SolidColorBrush(Colors.LightGreen);
timer.Start();
}
private void HandleTimerTick(object sender, EventArgs e)
{
Timer timer = (Timer)sender;
timer.Stop();
myButton.Dispatcher.BeginInvoke((Action)delegate()
{
myButton.Background = new SolidColorBrush(Colors.Red);
});
}
it works but just 5 seconds from my first click and the timer not resets every time I've click the button.
Thanks for your help.
You have to move the timer out of the event and restart it every time the user clicks. Something along these lines:
public partial class MainWindow : Window
{
private Timer timer;
public MainWindow()
{
InitializeComponent();
timer = new Timer{Interval = 5000};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
timer.Elapsed += HandleTimerTick;
myButton.Background = new SolidColorBrush(Colors.LightGreen);
timer.Stop();
timer.Start();
}
private void HandleTimerTick(object sender, EventArgs e)
{
Timer timer = (Timer)sender;
timer.Stop();
myButton.Dispatcher.BeginInvoke((Action)delegate()
{
myButton.Background = new SolidColorBrush(Colors.Red);
});
}
}

how to use timer effectively in c#

I have to show one form for about 5 sec and then I have to close that form and then show some other form once the new form is shown the timer has to stop.
I have difficulty in doing this.
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
Form5 f5 = new Form5();
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
Form5 f5 = new Form5();
f5.Hide();
}
try this code
Form5 f5 = new Form5();
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
MyTimer.stop();
f5.Hide();
}
Pull the declaration of Form5 outside of the functions, so it is a field. As it stands, each function has a different instance of this class.
Form5 f5 = new Form5();
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
MyTimer.Stop();
f5.Hide();
}
Note: You really should rename your form classes and the variables - f6 is meaningless. Call it what it is.
try this
Form5 f5 = new Form5(); //declare form obj globally
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
f5.Show();
f5.label7.Text = label6.Text;
MyTimer.Interval = 5000; // 0.5 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
MessageBox.Show("All The Best for Your Test and Your Time Starts Now.");
Form6 f6 = new Form6();
f6.Show();
MyTimer.Enabled = false;
f5.Hide();
}
I see several potential problems. First, you should setup your timer only once, perhaps at Form construction time, you don't need to set the interval and wire up an even handler every single time radioButton1's check state changes.
Inside of MyTimer_Tick, the first line should be calling MyTimer.Stop() (just call stop, you don't need to mess with Enabled, they do the same thing).
THEN you can display the MessageBox (which is modal and blocking), show Form6, hide f5, etc.
Think of MessageBox.Show() as a really long running call. It doesn't return until the message box is dismissed (it can easily take more than 5 seconds or any arbitrary amount of time). While the MessageBox is up, timer tick events are still queuing up (because the line that stops the timer hasn't been executed yet). It would be worth looking up the documentation for MessageBox.Show() and reading about what a modal dialog is and how its different from the alternative.
And try and clean up the names as other's have pointed out.
I think You're making it to difficult. If I understood You correctly...
Just add a timer to form5, set it's properties Enabled = true; and Interavl = 1000; (1000 miliseconds or 1 second). and just add timer tick event handler to your form5 timer like
private int _start = 0;
private int _seconds = 5;
private void timer1_Tick(object sender, EventArgs e)
{
_start++;
if(_start >= _seconds)
{
Close();
}
}
_start and _seconds should be initialized like form class private fields, or properties before event handler. This code works fine for me, and it closes form5 after 5 seconds it was shown. If you want to make this more flexible, for example if you want to set how many seconds form5 should be shown U can, for example, reload form5 constructor like ...
public Form5(int seconds)
{
InitializeComponent();
_seconds = seconds;
}
and in form1, when you create form5 pass number of seconds U want to show form5 as parameter:
Form5 f5 = new Form5(5);
also I think it would be better to create new instance of form 5 dirrectly in event handler
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
new Form5(10).Show(); // show form5 for 10 seconds
...
}
If U want to show some another more form after form5 close, just show it before form5 close in timer tick event handler:
private void timer1_Tick(object sender, EventArgs e)
{
_start++;
if(_start >= _seconds)
{
new Form2().Show();
Close();
}
}

Timer continuously firing in C#, Not able to stop

Could any one help me to stop my timer in windows form C3 application? I added timer in form using designer and interval is set as 1000; I would like to do some actions after 5 seconds of waiting after button click. Please check the code and advise me. Problem now is I get MessageBox2 infinitely and never gets the timer stop.
static int count;
public Form1()
{
InitializeComponent();
timer1.Tick += timer1_Tick;
}
public void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
while(count>5)
{
....dosome actions...
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count1++;
MessageBox.Show("Messagebox2");
if (count1 == 5)
{
//timer1.Enabled = false; timer1.Stop();
((System.Timers.Timer)sender).Enabled = false;
MessageBox.Show("stopping timer");
}
}
I would render the count useless and just use the timer 1 interval property and put your actions in the timer1_Tick event.
public void button1_Click(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
MessageBox.Show("stopping timer");
// Your other actions here
}
You are incrementing count1 and checking count.
while(count1 > 5)
{
...dosome actions...
}
Which Timer do you use? Because C# supports class Timer from two different namespaces. One is from Forms, the other is from System.Timers. I would suggest you to use the other one - System.Timers.Timer.
Timer t = new Timer(20000); // created with 20seconds
t.Enabled = true; // enables firing Elapsed event
t.Elapsed += (s, e) => {
\\do stuff
};
t.Start();
In this short code you can see how the timer is created and enabled. By registering to the Elapsed event you explicitly say what to do after the time elapses. and this is done just once. Of course, there are some changes needed in case user clicks button before your limit is reached. But this is highly dependent on behavior of the action you demand.

Categories