每隔X秒执行一次指定的函数
本文关键字:一次 函数 执行 每隔 | 更新日期: 2023-09-27 17:57:52
我有一个用C#编写的Windows窗体应用程序。无论打印机是否联机,以下功能都会进行检查:
public void isonline()
{
PrinterSettings settings = new PrinterSettings();
if (CheckPrinter(settings.PrinterName) == "offline")
{
pictureBox1.Image = pictureBox1.ErrorImage;
}
}
并且如果打印机离线则更新图像。现在,我如何每2秒执行一次这个函数isonline()
,这样当我拔下打印机时,表单上显示的图像(pictureBox1
)就会变成另一个,而无需重新启动应用程序或进行手动检查?(例如,通过按下运行isonline()
功能的"刷新"按钮)
使用系统。Windows。表格。计时器。
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()
。
。NET 6中添加了CCD_ 6类。
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"));
PeriodicTimer
相对于Timer.Delay
循环的主要优点在执行慢速任务时得到了最好的观察。
using System.Diagnostics;
var stopwatch = Stopwatch.StartNew();
// Uncomment to run this section
//while (true)
//{
// await Task.Delay(1000);
// Console.WriteLine($"Delay Time: {stopwatch.ElapsedMilliseconds}");
// await SomeLongTask();
//}
//Delay Time: 1007
//Delay Time: 2535
//Delay Time: 4062
//Delay Time: 5584
//Delay Time: 7104
var periodicTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(1000));
while (await periodicTimer.WaitForNextTickAsync())
{
Console.WriteLine($"Periodic Time: {stopwatch.ElapsedMilliseconds}");
await SomeLongTask();
}
//Periodic Time: 1016
//Periodic Time: 2027
//Periodic Time: 3002
//Periodic Time: 4009
//Periodic Time: 5018
async Task SomeLongTask()
{
await Task.Delay(500);
}
PeriodicTimer
将尝试每n*延迟秒调用一次,而Timer.Delay
将每n*(延迟+方法运行时间)秒调用一个,导致执行时间逐渐不同步。
最适合初学者的解决方案是:
从工具箱中拖动一个Timer,为其指定一个Name,设置所需的Interval,并将"Enabled"设置为True。然后双击Timer,Visual Studio(或您正在使用的任何东西)将为您编写以下代码:
private void wait_Tick(object sender, EventArgs e)
{
refreshText(); // Add the method you want to call here.
}
无需担心将其粘贴到错误的代码块或类似的东西中。
线程化:
/// <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;
}
随着时间的推移,情况发生了很大变化。您可以使用以下解决方案:
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(来自设计器)并设置它的Tick函数来运行isonline函数,从而轻松实现这一点。
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));
}
}
}