使用System.Timers.Timer的线程中的倒数计时器
本文关键字:倒数 计时器 线程 使用 Timers Timer System | 更新日期: 2023-09-27 17:55:34
我需要在主 UI 线程以外的另一个线程中运行倒数计时器。因此我不能使用DispatcherTimer
,因为它只存在于主线程中。因此,我需要一些System.Timers.Timer
帮助 - 我找不到任何关于如何在网络上创建倒数计时器的好例子。
到目前为止,我得到了:
Private void CountdownThread()
{
// Calculate the total running time
int runningTime = time.Sum(x => Convert.ToInt32(x));
// Convert to seconds
int totalRunningTime = runningTime * 60;
// New timer
System.Timers.Timer t = new System.Timers.Timer(1000);
t.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => totalRunningTime--;
// Update the label in the GUI
lblRunning.Dispatcher.BeginInvoke((Action)(() => {lblRunning.Content = totalRunningTime.ToString(@"hh':mm':ss");}));
}
标签lblRunning
显示倒计时值。
编辑:问题是我不知道如何在单独的线程中制作倒数计时器并从该线程更新标签!
使用 System.Threading.Tasks
在主 UI 线程上计划工作时,不会阻止主 UI 线程。可以在按钮单击事件上使用 async
关键字并执行一些计划工作,例如保存到数据库。当按钮单击事件保存到数据库时,用户仍然可以使用 UI 并执行其他操作。
重新驾驶:使用任务不会阻塞 UI 线程;这只是安排要在一段时间内完成的工作。在该持续时间内,它不会消耗任何线程的时间 - UI 线程或任何其他线程都不会消耗)。
因此,实际上可以使用DispatcherTimer
而不是System.Timers.Timer
命名空间,因为不需要新线程,也不会阻止任何线程。
使用 DispatcherTime
的倒数计时器的示例代码如下所示:
namespace CountdownTimer
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
TimeSpan runningTime;
DispatcherTimer dt;
public MainWindow()
{
InitializeComponent();
// Fill in number of seconds to be countdown from
runningTime = TimeSpan.FromSeconds(21600);
dt = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
lblTime.Content = runningTime.ToString(@"hh':mm':ss");
if (runningTime == TimeSpan.Zero) dt.Stop();
runningTime = runningTime.Add(TimeSpan.FromSeconds(-1));
}, Application.Current.Dispatcher);
dt.Start();
}
}
}
您需要
Start()
计时器并在每次刻度更新/使UI失效:
private void CountdownThread() {
// Calculate the total running time
int runningTime = time.Sum(x => Convert.ToInt32(x));
// Convert to seconds
int totalRunningTime = runningTime * 60;
// New timer
System.Timers.Timer t = new System.Timers.Timer(1000);
t.Elapsed += (s, e) => {
totalRunningTime--;
// Update the label in the GUI
lblRunning.Dispatcher.BeginInvoke((Action)(() => {
lblRunning.Content = TimeSpan.FromSeconds(totalRunningTime).ToString();
}));
};
// Start the timer!
t.Start();
}