I have a textBox2 on my windows form (confirmed name & spelling) I drug a timer from the toolbox over to my windows form and it is named timer1. I am trying to have the timer begin when the button is pressed and have textBox2 show each incrementing second so it shows a running time of how long the entire process has taken. Where did I err?
public partial class Form1 : Form
{
private int duration = 0;
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Start();
First();
Second();
Thirds();
Fourth();
Fifth();
timer1.Stop();
}
private void timer1_Tick(object sender, EventArgs e)
{
duration++;
textBox2.Text = duration.ToString();
}
}
It's not clear what the methods First()
, Second()
, and so on represent. But based on the rest of the code, it seems likely those are long-running tasks that you are trying to time.
In any case, the problem is that you never return from the button1_Click()
method until after you've stopped the timer. The timer ticks are raised in the UI thread, and can only be raised if the UI thread is not blocked by the handling of some other event. Like the handling of button1
's Click
event.
You should be executing your long-running operations in a separate thread, eg using Task
. Then the timer will work correctly, or you can even just use a loop in an async
method to display the elapsed time, whichever you prefer.
For example:
private int duration = 0;
private async void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Start();
await Task.Run(() =>
{
First();
Second();
Thirds();
Fourth();
Fifth();
});
timer1.Stop();
}
private void timer1_Tick(object sender, EventArgs e)
{
duration++;
textBox2.Text = duration.ToString();
}
Notes:
await
feature, new to C# 5.0, is used in the example above. See below for a different approach that is compatible with older versions of C# and .NET. await
, the async
method in which the statement is contained will execute up to the "awaited" expression. At that point, control of the thread is yielded back to the caller of the async
method. Later, when the awaited expression finally completes, control of the thread is returned back to the async
method at the point where it previously yielded (ie the await
statement). Task
, are executed asynchronously in a different thread. When that Task
is started, the button1_Click()
method actually returns to its caller. If and when they (ie that Task
) finally complete, execution of the button1_Click()
method will resume, at the next statement: timer1.Stop()
.
The async
/ await
feature makes code that uses asynchronous operations a lot easier to write. But even before that, there are other mechanisms to do the same thing. Here is one such mechanism, using the BackgroundWorker
object:
private async void button1_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (sender1, e1) =>
{
First();
Second();
Thirds();
Fourth();
Fifth();
};
worker.RunWorkerCompleted += (sender1, e1) =>
{
timer1.Stop();
};
timer1.Enabled = true;
timer1.Start();
worker.RunWorkerAsync();
}
Notes:
BackgroundWorker
object is created, it captures the current synchronization context (if any), which will be used later to raise all of the BackgroundWorker
events except DoWork
. DoWork
event is raised using a thread pool thread, ie some thread other than the main UI thread. This allows things to happen on the UI thread even while the long-running work is being executed. DoWork
and RunWorkerCompleted
events. BackgroundWorker
itself. It is only when the RunWorkerAsync()
method is called that the worker starts running, by raising the DoWork
event.
By the way, while I left your original code as intact as possible, please do note that you don't need both the timer1.Enabled = true;
and the timer1.Start()
. Either suffices to start the timer; you can use whichever one you like and leave out the other.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.