【问题标题】:Creating a background timer to run asynchronously创建后台计时器以异步运行
【发布时间】:2013-03-30 13:22:15
【问题描述】:

我真的在为此苦苦挣扎。我正在 Visual Studio 中创建一个 winforms 应用程序,需要一个每半小时计时一次的后台计时器 - 这样做的目的是从服务器上拉下更新。

我尝试了几种不同的方法,但都失败了,要么是由于教程/示例不佳,要么是我自己在 C# 中的缺点。我认为向您展示我迄今为止所做的尝试是浪费时间,因为我所尝试的似乎离目标很远。

有谁知道实现异步后台计时器的一种清晰而简单的方法,C# 新手很容易理解?

【问题讨论】:

  • 我假设您使用的是System.Timers.Timer?
  • 在我看来最重要的问题是:定时器运行时会发生多少工作?这将对您的程序的响应性产生什么影响。请注意,所有 WinForms 应用程序都在一个 UI 线程中运行,如果该线程突然忙于从服务器中提取一些数据,您的用户可能不喜欢它,所以问题是,您是否需要多线程解决方案。
  • 这不是一个特别繁重的过程。只需从服务器获取数据表,然后根据表的内容运行一些 SQL。大多数时候无论如何都不会返回任何东西。
  • @Terfi:那么最好使用 System.Windows.Forms.Timer 和 System.Windows.Threading.DispatcherTimer。这些很方便,因为它们在 GUI 线程上执行代码,因此不需要显式调用调用。这些计时器适用于 GUI 的快速定期更新。如果代码运行时间更长,则应将 System.Threading.Timer 与显式 Invoke 一起用于更新部分

标签: c# winforms asynchronous timer


【解决方案1】:
    // Create a 30 min timer 
    timer = new System.Timers.Timer(1800000);

    // Hook up the Elapsed event for the timer.
    timer.Elapsed += OnTimedEvent;

    timer.Enabled = true;


...

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // do stuff
}

通常需要注意的是:计时器不会非常准确,可能需要GC.KeepAlive(timer)

另请参阅:Why does a System.Timers.Timer survive GC but not System.Threading.Timer?

【讨论】:

  • 这是最简单的方法。 +1
  • 天哪,这太容易了!需要有更好的例子,这样可以更容易地找到。谢谢!
  • 您可以进一步简化它:timer.Elapsed += OnTimedEvent; 您可能会丢失new ElapsedEventHandler 部分。
  • 根据stackoverflow.com/q/4962172/116818,你不需要GC.KeepAlive(timer),定时器自己做。
【解决方案2】:

在表单中声明成员变量:

System.Timers.Timer theTimer;

在表单加载时(或任何其他需要开始更新轮询的时间),请执行以下操作:

theTimer = new System.Timers.Timer(1800000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();

像这样声明您的 PollUpdates 成员函数:

private void PollUpdates(object sender, EventArgs e)
{
}

【讨论】:

  • 很抱歉可能与 Mitch Wheat 的回答重复,我同时发布了它:)
  • 是的,但还是谢谢!不幸的是,我只能将一个答案标记为已接受,并且由于米奇首先回答,所以我标记他的答案是公平的。但我已经 +1 了你的 - 谢谢 :)
【解决方案3】:

我认为您需要了解所有计时器类。请参阅下面 Jon 的回答。

你用的是什么类型的定时器?

  1. System.Windows.Forms.Timer 将在 UI 线程中执行
  2. System.Timers.Timer 在线程池线程中执行,除非您 指定一个 SynchronizingObject
  3. System.Threading.Timer 在线程池线程中执行其回调

在所有情况下,计时器本身都是异步的 - 在触发之前它不会“占用”线程。

来源:Do .NET Timers Run Asynchronously?

【讨论】:

  • -1:答案是乔恩答案的逐字转载。因此,它更适合作为评论。
  • 通常情况下是这样,但我们说的是 Jon Skeet。 +1。
猜你喜欢
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 2019-08-18
  • 2016-03-02
相关资源
最近更新 更多