使用System.Timers.Timer的线程中的倒计时计时器

时间:2015-06-11 15:43:07

标签: c# multithreading timer

我需要在主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显示倒计时值。

编辑:问题是我不知道如何在单独的线程中制作倒数计时器并从该线程更新标签!

2 个答案:

答案 0 :(得分:0)

您需要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();
}   

答案 1 :(得分:0)

使用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();
       }
   }
}