【问题标题】:Implement multiple timers in C#在 C# 中实现多个计时器
【发布时间】:2012-09-07 08:44:14
【问题描述】:

我正在开发一个 Windows 窗体应用程序,我在其中有几个所谓的“服务”,用于轮询来自各种服务(如 Twitter、Facebook、天气、金融)的数据。现在我的每个服务都有其单独的轮询间隔设置,所以我想我可以为我的每个服务实现一个System.Windows.Forms.Timer 并相应地设置它的Interval 属性,以便每个计时器以预设的间隔触发一个事件,这将导致最好通过BackgroundWorker 异步拉取新数据的服务。

这是最好的方法吗?或者它会减慢我的应用程序导致性能问题。有没有更好的方法?

谢谢!

【问题讨论】:

  • 这是一个很好的方法,但是,如果源的数量非常多,您可以考虑使用调度程序而不是多个计时器(因为计时器是 - 不是那么轻 - 有限的资源) .

标签: c# winforms timer backgroundworker


【解决方案1】:

你可以用一个Timer 来做到这一点,只需要更聪明的间隔方法:

public partial class Form1 : Form
{
    int facebookInterval = 5; //5 sec
    int twitterInterval = 7; //7 sec

    public Form1()
    {
        InitializeComponent();

        Timer t = new Timer();
        t.Interval = 1000; //1 sec
        t.Tick += new EventHandler(t_Tick);
        t.Start();
    }

    void t_Tick(object sender, EventArgs e)
    {
        facebookInterval--;
        twitterInterval--;

        if (facebookInterval == 0)
        {
            MessageBox.Show("Getting FB data");
            facebookInterval = 5; //reset to base value
        }

        if (twitterInterval == 0)
        {
            MessageBox.Show("Getting Twitter data");
            twitterInterval = 7; //reset to base value
        }
    }
}

【讨论】:

  • 我也想过,这是在资源有限的微控制器上使用计时器时的标准方法。然而,问题是哪种方式更有效:多个定时器还是带有内部计数器的单个定时器?在我看来,第二种方式会更有效,资源更明智。谢谢!
  • 我想像Timer 这样的复杂结构比简单的整数要大得多;)更小 = 访问和处理速度更快。
【解决方案2】:

你并不真的需要 BackgroundWorker,因为 WebClient 类有 Async 方法。

因此您可能只需为每个“服务”设置一个 WebClient 对象并使用如下代码:

facebookClient = new WebClient();
facebookClient.DownloadStringCompleted += FacebookDownloadComplete;
twitterClient = new WebClient();
twitterClient.DownloadStringCompleted += TwitterDownloadComplete;

private void FacebookDownloadComplete(Object sender, DownloadStringCompletedEventArgs e)
{
    if (!e.Cancelled && e.Error == null)
    {
        string str = (string)e.Result;
        DisplayFacebookContent(str);
    }
}
private void OnFacebookTimer(object sender, ElapsedEventArgs e)
{
     if( facebookClient.IsBusy) 
         facebookClient.CancelAsync(); // long time should have passed, better cancel
     facebookClient.DownloadStringAsync(facebookUri);
}

【讨论】:

  • 感谢您的建议,但我没有提到我正在使用可用的 API,有些有异步方法,有些没有,所以我只需要单独调整。
猜你喜欢
  • 2012-05-26
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 2013-09-21
  • 2016-07-21
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多