I am making a WinForm program that uses the SerialPort to control the amount of light. 100% for the first 10 minutes, 97% for the next 20 minutes, and 94% for the remaining 30 minutes.
The problem occur when I force close the program. I don't have a way to turn off the lights currenly working.
Is there any way to solve this?
Edit
Is it possible to create an event that occurs just before the program exits?
Based on #Mong Zhu's answer, I solved it like this:
FormClosing += (sender, e) =>
{
if (serialPort.IsOpen)
{
serialPort.WriteBytes(Percent0); // turning off the light
serialPort.Close();
}
};
If you add a Form.Closing event, it will work not only when the form closes, but also when the process exits.
Related
I have some C# controls like NumericUpDown or TextBox and want to fire an event with an offset of some seconds. In the past, I have accomplished this behaviour with a Timer. The code which I am working on uses a BackgroundWorker to accomplish this. On some other places, I found normal Threads to build this behaviour.
The reason why one might want an offset is, for example, a time-consuming method which is executed after each ValueChange of a NumericUpDown. If a user clicks several times on the down arrow only the last Click should be of importance because this is the value which the user wanted in the end.
The way I used to handle this looks as follows
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
/*
* Designer Code
this.eventOffsetTimer.Interval = 500;
this.eventOffsetTimer.Tick += new System.EventHandler(this.eventOffsetTimer_Tick);
*/
eventOffsetTimer.Stop();
eventOffsetTimer.Start();
}
private void eventOffsetTimer_Tick(object sender, EventArgs e)
{
eventOffsetTimer.Stop();
//Time consuming stuff...
MessageBox.Show(numericUpDown1.Value.ToString());
}
I was wondering what the best practice is to accomplish an offset of some seconds before the event is fired. Is there a built-in way which Microsoft encourages to use? Starting and stopping a Timer is a simple thing to do but it seems there could be a Microsoft encouraged method.
You should use .Restart(). It first releases Timer then Starts it again.
Tips: You do not need to use .Stop() with .Restart()
This question already has answers here:
Implementing a pause in WPF
(3 answers)
Closed 9 years ago.
I have a WPF app and I want to sleep for a second before displaying certain info on screen. So its.
1. Click a button.
Sleep 1 sec.
Display a label.
Sleep 1 sec.
Display a label.
etc etc
private void RunTest()
{
clearTable();
System.Threading.Thread.Sleep(1000);
this.Cursor = Cursors.Wait;
Label_OS_Result.Content = operatingSystem;
Image_OS.Visibility = Visibility.Visible;
System.Threading.Thread.Sleep(1000);
Label_CPU_Result.Content = procName;
Image_CPU.Visibility = Visibility.Visible;
System.Threading.Thread.Sleep(1000);
}
But when I click my button it seems to wait for a few seconds and then displays everything all at once.
Whats going on here??
It is working as it is expected.
Thread.Sleep stops the execution of the current thread for specified amount of time. So, when you change the visibility of an image, it will make further calls to change the visibility in the framework, then it will try to draw it on screen (invalidates). When you sleep the thread before this operation finishes it will not have enough time to finish this operation. You are simply blocking the UI thread responsible of drawing something on the screen.
Beware that Thread.Sleep may not be the solution, it is better for you to have a look at DispatcherTimer or BackgroundWorkers.
You don't want to Thead.Sleep() on the thread displaying your GUI.
Instead, you should try await Task.Delay(). This is similar to sleep, but it won't block the GUI thread.
This will allow all the rendering to still happen, while delaying the visiblity changes for your labels.
It is working as intended.
It may not be what you expected, but the problem here is your expectations.
What happens when you fiddle with properties on most visual controls, that should end up changing the appearance of the control, is first to make the internal adjustments to the controls properties (ie. data), and then trigger a redraw. To trigger the redraw, a message is usually posted to the message queue of the thread that owns this visual control.
This thread usually processes messages one at a time, be it a button click, mouse movement, or the paint messages that was just posted because you changed the image.
However, that thread is basically written like this (pseudo-code):
while (true)
{
var message = GetNextMessageFromQueue();
ProcessMessage(message);
}
The last time this loop was active, it started processing a message that ended up calling your code, the one that is now sleeping.
So basically, to get the message pump (the typical name of the code that implements this loop) to continue pumping messages, and thus process your paint message, is not to sleep.
You might want to separate your processing out to a different thread, or some other asynchronous way of doing things "in the background".
Note that you will get the same problem if you start doing any kind of lengthy processing in response to a button click or similar, without doing it on a background thread (or again, some other asynchronous way). The GUI will appear to have frozen.
This problem, however, is so common that Microsoft ended up building in special support for it in Windows. It used to be that a window just seemed to hang. Now, however, if the message queue "fills up", Windows will fade out the windows and tack on a caption to it indicating that it has stopped responding. Not a solution, but slightly better.
Sleep function is behaving correct.
Better you use a Timer to do so,
// Declare it in the constructor of the class
int level = 0;
Timer timer = new Timer
timer.Interval = 1000;
timer.Tick +=new EventHandler(timer_Tick);
private void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
if (level == 0)
{
Label_OS_Result.Content = operatingSystem;
Image_OS.Visibility = Visibility.Visible;
++level;
}
else if (level == 1)
{
Label_CPU_Result.Content = procName;
Image_CPU.Visibility = Visibility.Visible;
++level;
}
else if (level > 1)
{
this.Cursor = Cursors.Default;
return;
}
timer.Start();
}
private void RunTest()
{
clearTable();
//System.Threading.Thread.Sleep(1000);
timer.Start();
this.Cursor = Cursors.Wait;
}
I have a web application that generates enlarged images of smaller images uploaded by other team and stops if no image is left in uploaded folder.
A button needs to be clicked to start generating image and restart every time it finishes.
Can this click event be fired automatically at regular interval say at 15 minutes or better still just as the application stops.
A similar question was asked on earlier thread How to write C# Scheduler .
private void OnTimerTick()
{
if (DateTime.Now.Minutes % 15 == 0)
{
// Do something
}
}
Where should I place timer to call below code ?
protected void btnImgGenerate_click()
{
// Application code
}
Is there a way to check whether a web application in asp.net has stopped executing and then restart it automatically?
Using timer, I can schedule application to start and stop at specific time of day and keep application running throughout specified duration of day using second method.
You can add code to initialize timer from the System.Threading namespace in Global.asax file and configure it to execute some functionality with desired periodicy. But if your application crashes you'll get following issue:
Is there a way to check whether a web application in asp.net has
stopped executing and then restart it automatically ?
Using timer , I can schedule application to start and stop at specific
time of day and keep application running throughout specified duration
of day using second method .
Nope. You can't start web appliccation from itself if it stopped by some reasons and no new requests comes. So in my opinion for your purpose better suited a windows service.
A jQuery implementation for clicking a button after 15 minutes (which will cause a postback and trigger your event) is:
$(document).ready(function(){
setTimeout(function(){$('btnImgGenerate').click();},900000);
});
Have a Button click event that starts the timer-
protected void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
and in the timer Tick event, you can do something like this-
protected void timer1_Tick(object sender, EventArgs e)
{
timer1.enabled=false;
//do your coding
timer1.enabled= true;
}
So once you click the button the timer starts, does all the operations and at the end restarts automatically, after you set timer1.enabled to true.
If you are looking for automating this without the click event, you can use the javascript setInterval() Method-
See the example here-
http://www.w3schools.com/jsref/met_win_setinterval.asp
Solved:
You guys are the best!
I took al the content of goyouidiot_Click and made it into a method called displayResult, and then:
private void t1_TextChanged(object sender, EventArgs e)
{
displayResult();
}
How didn't i thought of that before? lol, thx
here is original messege:
No lone ago i built a little software
that calculates an averege of 15
numbers. The code starts to run when
the buttun is clicked, but i want to
put this code in an infinate loop that
starts to run with program, so the
answer will be auto updated. this is
my code:
private void goyouidiot_Click(object sender,
EventArgs e)
{
.
.
.
.
}
and those who havn't understood:
I have 15 text-boxs, and I want
the method to run when the text boxs'
content changes.
Rather than make an infinite loop (which will cause the application to hang unless it's on a background thread - a much bigger can of worms) you should just respond to change events.
If your numbers are being updated in text boxes, just bind the TextChanged events of each of them to your goyouidiot_Click method - which you should then rename.
Edit
As Eric points out in his answer, the reason these events work is because there is in fact an infinite loop in the background to listen for changes - the Windows message pump. This loop is started when you call the Run method on your application.
Your intuition that an infinite loop must be involved is correct. But you don't want to write that loop yourself; the runtime library has already written it for you. What you want to read up on is event-driven programming. Find a good introduction, like, say:
http://www.c-sharpcorner.com/UploadFile/sksaha/EventsinNet11152005043514AM/EventsinNet.aspx
The way event-driven programming works behind the scenes is that there is an infinite loop of code that monitors the state of a queue of messages coming in from the operating system. The messages are representing things like mouse clicks and typing. The infinite loop code then turns those messages into event firings. You can listen to those event firings and run code when particular events happen.
Putting it in a infinite loop could starve the system of CPU power, meaning you will need to introduce a pause (Thread.Sleep).
If you use a pause, you may as well use a Timer object - there is a form's based Timer or a thread based Timer (System.Windows.Forms, or System.Threading / System.Timers);
I would personally suggest using a timer to tick at a desired interval.
A thread timer uses delegates / thread pool whereas the forms based timer places messages on the message pump - both are not guaranteed to be accurate to their intervals due to the overhead in the way in which a tick is created.
If I understand correctly (you want to update something every 15 minutes in your Winform application), then it is better to use the Timer class, which will run your code periodically.
EDIT: If you want to perform some calculations when a text is changed in one of the text boxes, you should do it in an event handler for the TextChanged event of these text boxes (you want to assign the same handler to every text box)
I have a C# windows forms application. The way I currently have it set up, when Form1_Load() runs it checks for recovered unsaved data and if it finds some it prompts the user if they want to open that data. When the program runs it works alright but the message box is shown right away and the main program form (Form1) does not show until after the user clicks yes or no. I would like the Form1 to pop up first and then the message box prompt.
Now to get around this problem before I have created a timer in my Form, started the timer in the Form1_Load() method, and then performed the check and user prompt in the first Timer Tick Event. This technique solves the problem but is seems like there might be a better way.
Do you guys have any better ideas?
Edit: I think I have also used a background worker to do something similar. It just seems kinda goofy to go through all the trouble of invoking the method to back to the form thread and all that crap just to have it delayed a couple milliseconds!
I would use Form1_Shown()
Use the Shown event. It seems to suit what you need, and will only display the first time the form is shown.
Form f1 = new Form();
f1.Shown += new EventHandler(f1_Shown);
public void f1_Shown(object sender, EventArgs e)
{
// Show dialog in here
}
Try the "Shown" event:
Form.Show Event
Using a Windows.Forms.Timer is a good, stable, well-known, and easily understood technique for doing what you want. I would avoid any other timer objects.
The form's Shown event works well.
Overload / override the Show method. (My preferred technique for greater control.) In this method, I would do the checking needed. When ready, I would call the base.Show method, then do any other processing, such as message boxes, prompts, logging, or whatever.