在函数完成其任务后定期执行函数

时间:2013-02-19 05:36:25

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

我正在使用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分钟,它再次执行。

2 个答案:

答案 0 :(得分:6)

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分钟,则执行正常进行。

答案 1 :(得分:4)

我认为更简单的方法是使用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,可用于检测错误。