【问题标题】:Execute specified function every X seconds每 X 秒执行一次指定函数
【发布时间】:2011-09-04 09:16:17
【问题描述】:

我有一个用 C# 编写的 Windows 窗体应用程序。以下函数检查打印机是否在线:

public void isonline()
{
    PrinterSettings settings = new PrinterSettings();
    if (CheckPrinter(settings.PrinterName) == "offline")
    {
        pictureBox1.Image = pictureBox1.ErrorImage;
    }
}

并在打印机离线时更新图像。现在,如何每 2 秒执行一次此功能isonline(),以便当我拔下打印机时,表单上显示的图像 (pictureBox1) 会变成另一个图像,而无需重新启动应用程序或进行手动检查? (例如,按下运行isonline() 函数的“刷新”按钮)

【问题讨论】:

标签: c# .net winforms


【解决方案1】:

使用System.Windows.Forms.Timer

private Timer timer1; 
public void InitTimer()
{
    timer1 = new Timer();
    timer1.Tick += new EventHandler(timer1_Tick);
    timer1.Interval = 2000; // in miliseconds
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    isonline();
}

您可以在Form1_Load() 中拨打InitTimer()

【讨论】:

  • 应用启动后会自动执行吗?它不适合我那样。你能提出一些解决方案吗?谢谢
  • @user2886091:只要计时器没有被释放或停止,它应该可以工作
  • new EventHandler 还需要吗?
  • 事件处理部分在prntscr.com/e1sl9t截图中出现错误
  • Timer 对象现在似乎有不同的配置。我使它工作使用:timer = new Timer(TimerCallback, null, 0, timeStepInMilliseconds) + private static void TimerCallback(Object stateInfo)
【解决方案2】:

最适合初学者的解决方案是:

从工具箱中拖出一个计时器,为其命名,设置所需的时间间隔,并将“启用”设置为 True。然后双击 Timer,Visual Studio(或任何你正在使用的)将为你编写以下代码:

private void wait_Tick(object sender, EventArgs e)
{
    refreshText(); // Add the method you want to call here.
}

无需担心将其粘贴到错误的代码块或类似的东西中。

【讨论】:

  • 喜欢它,正是我想要的。
【解决方案3】:

线程:

    /// <summary>
    /// Usage: var timer = SetIntervalThread(DoThis, 1000);
    /// UI Usage: BeginInvoke((Action)(() =>{ SetIntervalThread(DoThis, 1000); }));
    /// </summary>
    /// <returns>Returns a timer object which can be disposed.</returns>
    public static System.Threading.Timer SetIntervalThread(Action Act, int Interval)
    {
        TimerStateManager state = new TimerStateManager();
        System.Threading.Timer tmr = new System.Threading.Timer(new TimerCallback(_ => Act()), state, Interval, Interval);
        state.TimerObject = tmr;
        return tmr;
    }

常规

    /// <summary>
    /// Usage: var timer = SetInterval(DoThis, 1000);
    /// UI Usage: BeginInvoke((Action)(() =>{ SetInterval(DoThis, 1000); }));
    /// </summary>
    /// <returns>Returns a timer object which can be stopped and disposed.</returns>
    public static System.Timers.Timer SetInterval(Action Act, int Interval)
    {
        System.Timers.Timer tmr = new System.Timers.Timer();
        tmr.Elapsed += (sender, args) => Act();
        tmr.AutoReset = true;
        tmr.Interval = Interval;
        tmr.Start();

        return tmr;
    }

【讨论】:

    【解决方案4】:

    您可以通过将计时器添加到您的表单(来自设计器)并设置它的 Tick 函数来运行您的 isonline 函数来轻松地做到这一点。

    【讨论】:

      【解决方案5】:

      随着时间的推移,情况发生了很大变化。 您可以使用以下解决方案:

      static void Main(string[] args)
      {
          var timer = new Timer(Callback, null, 0, 2000);
      
          //Dispose the timer
          timer.Dispose();
      }
      static void Callback(object? state)
      {
          //Your code here.
      }
      

      【讨论】:

      • 让我补充一下,这个 Timer 来自 System.Threading 命名空间。
      【解决方案6】:

      .NET 6 添加了PeriodicTimer 类。

      var periodicTimer= new PeriodicTimer(TimeSpan.FromSeconds(1));
      while (await periodicTimer.WaitForNextTickAsync())
      {
          // Place function in here..
          Console.WriteLine("Printing");
      }
      

      你可以在后台运行它:

      async Task RunInBackground(TimeSpan timeSpan, Action action)
      {
          var periodicTimer = new PeriodicTimer(timeSpan);
          while (await periodicTimer.WaitForNextTickAsync())
          {
              action();
          }
      }
      
      RunInBackground(TimeSpan.FromSeconds(1), () => Console.WriteLine("Printing"));
      

      【讨论】:

      • 这与内含 Task.Delay 的无限循环有何不同?
      • 显然Periodic Timer 比 Task.Delay 更有效,因为它没有重复任务或计时器分配source。它可能更容易阅读/理解,并可能标准化计时器循环。
      【解决方案7】:
      using System;
      using System.Timers;
      namespace SnirElgabsi
      {
        class Program
        {
           private static Timer timer1;
           static void Main(string[] args)
           {
               timer1 = new Timer(); //new Timer(1000);
               timer1.Elpased += (sender,e) =>
               {
                  MyFoo();
               }
               timer1.Interval = 1000;//miliseconds
               timer1.Start();
             
               Console.WriteLine("press any key to stop");
               Console.ReadKey();
           }
      
           private static void MyFoo()
           {
               Console.WriteLine(string.Format("{0}", DateTime.Now));
           }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多