[英]TextBox not being updated
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. 我在Windows窗体上有一个textBox2(确认名称和拼写),我将一个定时器从工具箱放到Windows窗体中,并将其命名为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.
我试图让计时器在按下按钮时开始计时,并让textBox2显示每个递增的秒数,以便它显示整个过程花费了多长时间的运行时间。 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. 目前尚不清楚
First()
, Second()
等方法代表什么。 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. 无论如何,问题在于,直到停止计时器后,您才可以从
button1_Click()
方法返回。 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. 计时器滴答声在UI线程中引发,并且仅在UI线程未被其他事件处理阻止时才引发。 Like the handling of
button1
's Click
event. 就像处理
button1
的Click
事件一样。
You should be executing your long-running operations in a separate thread, eg using Task
. 您应该在单独的线程中执行长时间运行的操作,例如使用
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. 然后计时器将正常工作,或者您甚至可以使用
async
方法中的循环来显示经过的时间,无论您选择哪个。
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. await
功能。 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. await
,包含该语句的async
方法将一直执行到“ awaited”表达式。 At that point, control of the thread is yielded back to the caller of the async
method. async
方法的调用者。 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). async
方法(即, await
语句)。 Task
, are executed asynchronously in a different thread. Task
中的五个方法在另一个线程中异步执行。 When that Task
is started, the button1_Click()
method actually returns to its caller. Task
时, button1_Click()
方法实际上返回其调用方。 If and when they (ie that Task
) finally complete, execution of the button1_Click()
method will resume, at the next statement: timer1.Stop()
. Task
)最终完成,当它们完成时,将在下timer1.Stop()
语句timer1.Stop()
处继续执行button1_Click()
方法。
The async
/ await
feature makes code that uses asynchronous operations a lot easier to write. async
/ await
功能使使用异步操作的代码更容易编写。 But even before that, there are other mechanisms to do the same thing. 但即使在此之前,还有其他机制可以做同样的事情。 Here is one such mechanism, using the
BackgroundWorker
object: 这是一种使用
BackgroundWorker
对象的机制:
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
. BackgroundWorker
对象时,它将捕获当前的同步上下文(如果有),稍后将用于引发除DoWork
之外的所有BackgroundWorker
事件。 DoWork
event is raised using a thread pool thread, ie some thread other than the main UI thread. DoWork
事件。 This allows things to happen on the UI thread even while the long-running work is being executed. DoWork
and RunWorkerCompleted
events. DoWork
和RunWorkerCompleted
事件的匿名方法之前声明的。 BackgroundWorker
itself. BackgroundWorker
本身。 It is only when the RunWorkerAsync()
method is called that the worker starts running, by raising the DoWork
event. RunWorkerAsync()
方法时,工作程序才会通过引发DoWork
事件来开始运行。
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;
顺便说一句,虽然我尽可能保留了原始代码,但请注意,您不需要同时使用
timer1.Enabled = true;
and the timer1.Start()
. 和
timer1.Start()
。 Either suffices to start the timer; 任一都足以启动计时器; you can use whichever one you like and leave out the other.
您可以使用任意一个,而忽略另一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.