【问题标题】:Executing a function periodically after the function completes its task在函数完成其任务后定期执行函数
【发布时间】:2013-02-03 17:24:49
【问题描述】:

我正在使用 C# 和 xaml 构建一个 Windows 商店应用程序。我需要在一定的时间间隔后刷新数据(从服务器带来新数据)。我使用 ThreadPoolTimer 定期执行刷新功能,如下所示:

   TimeSpan period = TimeSpan.FromMinutes(15); 
   ThreadPoolTimer PeriodicTimer =  ThreadPoolTimer.CreatePeriodicTimer(async(source)=> {  
   n++; 
   Debug.WriteLine("hello" + n);
   await dp.RefreshAsync(); //Function to refresh the data
   await Dispatcher.RunAsync(CoreDispatcherPriority.High,
                () =>
                {
                    bv.Text = "timer thread" + n;

                });

        }, period);

这工作正常。唯一的问题是,如果刷新函数在其下一个实例提交到线程池之前没有完成怎么办。有没有办法指定执行之间的差距。

第 1 步:执行刷新功能(需要任何时间)

第 2 步:刷新函数完成执行

第 3 步:间隔 15 分钟,然后转到第 1 步

刷新功能执行。执行结束15分钟后,再次执行。

【问题讨论】:

    标签: c# visual-studio-2012 threadpool windows-store-apps


    【解决方案1】:

    AutoResetEvent 将解决这个问题。声明一个类级别的 AutoResetEvent 实例。

    AutoResetEvent _refreshWaiter = new AutoResetEvent(true);
    

    然后在您的代码中:1. 等待它发出信号,然后 2. 将其引用作为参数传递给 RefreshAsync 方法。

    TimeSpan period = TimeSpan.FromMinutes(15); 
       ThreadPoolTimer PeriodicTimer =  ThreadPoolTimer.CreatePeriodicTimer(async(source)=> {  
       // 1. wait till signaled. execution will block here till _refreshWaiter.Set() is called.
       _refreshWaiter.WaitOne();
       n++; 
       Debug.WriteLine("hello" + n);
       // 2. pass _refreshWaiter reference as an argument
       await dp.RefreshAsync(_refreshWaiter); //Function to refresh the data
       await Dispatcher.RunAsync(CoreDispatcherPriority.High,
                    () =>
                    {
                        bv.Text = "timer thread" + n;
    
                    });
    
            }, period);
    

    最后,在dp.RefreshAsync 方法结束时,调用_refreshWaiter.Set();,这样如果15 秒过去了,就可以调用下一个RefreshAsync。请注意,如果 RefreshAsync 方法所用时间少于 15 分钟,则执行正常进行。

    【讨论】:

      【解决方案2】:

      我认为更简单的方法是使用async

      private async Task PeriodicallyRefreshDataAsync(TimeSpan period)
      {
        while (true)
        {
          n++; 
          Debug.WriteLine("hello" + n);
          await dp.RefreshAsync(); //Function to refresh the data
          bv.Text = "timer thread" + n;
          await Task.Delay(period);
        }
      }
      
      TimeSpan period = TimeSpan.FromMinutes(15); 
      Task refreshTask = PeriodicallyRefreshDataAsync(period);
      

      此解决方案还提供了一个Task,可用于检测错误。

      【讨论】:

        猜你喜欢
        • 2019-12-01
        • 2017-08-03
        • 1970-01-01
        • 2013-11-09
        • 2015-12-06
        • 1970-01-01
        • 2016-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多