C# 多个Windows.Forms.Timer,应用程序运行缓慢
我的问题是c窗体应用程序中有多个Windows.Forms.Timer时的性能 例如,timerHora的间隔为1秒,在标签中显示当前小时 我没有任何异步方法,因此,当我运行应用程序时,我的GUI不会每秒刷新小时标签,我猜它与其他计时器在同一线程中运行,并等待其他函数完成,因此它有时每秒刷新一次,其他时间为2、3或4秒C# 多个Windows.Forms.Timer,应用程序运行缓慢,c#,winforms,performance,timer,C#,Winforms,Performance,Timer,我的问题是c窗体应用程序中有多个Windows.Forms.Timer时的性能 例如,timerHora的间隔为1秒,在标签中显示当前小时 我没有任何异步方法,因此,当我运行应用程序时,我的GUI不会每秒刷新小时标签,我猜它与其他计时器在同一线程中运行,并等待其他函数完成,因此它有时每秒刷新一次,其他时间为2、3或4秒 所以。。。您能为我推荐处理此问题的最佳做法吗?问题可能是timmers事件太慢。 timmers是在主线程中执行的,因此如果您的代码很慢,那么您将减慢所有表单的速度 尝试使用线程
所以。。。您能为我推荐处理此问题的最佳做法吗?问题可能是timmers事件太慢。 timmers是在主线程中执行的,因此如果您的代码很慢,那么您将减慢所有表单的速度 尝试使用线程代替timmers您可以尝试
public partial class Form1 : Form
{
Task _task;
CancellationTokenSource _token;
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_token = new CancellationTokenSource();
_task = Task.Factory.StartNew(() => DoWork(), _token.Token);
}
protected override void OnClosing(CancelEventArgs e)
{
_token.Cancel();
Application.DoEvents();
_task.Wait();
base.OnClosing(e);
}
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
_task.Dispose();
_token.Dispose();
components.Dispose();
}
base.Dispose(disposing);
}
private void SetTime()
{
var dt = DateTime.Now;
label1.Text = $"{dt.Hour}:{dt.Minute}:{dt.Second}";
}
private void DoWork()
{
while (!_token.IsCancellationRequested)
{
if (InvokeRequired)
Invoke(new MethodInvoker(SetTime));
}
}
}
我需要为这些事件应用时间间隔,所以我想我还是需要计时器吧?还是我错了?谢谢^^@Ferus7通常,您会使用计时器在后台启动处理。不同的需求需要不同的方法-如果您只是在更新UI,那么除了winforms计时器之外,使用其他任何东西都没有意义。如果您需要偶尔从数据库更新UI,通常会将数据库更新作为计时器事件启动的后台任务运行,并在UI线程准备就绪等待时将结果整理回UI线程,这在大多数情况下都非常简单。尝试了@Luaan,thx,但我无法每秒刷新ui,因为其中有一些方法比较繁重:S@Ferus7同样,不要在UI线程上使用繁重的方法。这是您真正的问题——计时器事件稍后执行只是此问题的一个症状。不管定时器是什么,当重方法执行时,应用程序的UI仍然没有响应,这无论如何都是糟糕的UX。如果一个方法需要足够长的时间才能被注意到,根据具体情况,20-200ms是一个粗略的阈值,它不应该出现在UI线程上。好的@luan,真的谢谢你,我会尝试优化它^^你可以尝试减少计时器的数量,如中所示。另外,我建议您查看System.Timers.Timer而不是System.Windows.Forms.Timer可能会提供一些性能优势。谢谢,我会试试,如果这个计时器不起作用,我想我会尝试使用Threads System.Timers.Timer确实使用单独的线程进行回调。但是您仍然需要与UI同步以更改UI。听起来你在UI线程上做的工作比你应该做的多得多。将UI与阻塞和计算分开,UI将保持响应。这有很大帮助,我有一个问题,如果我想运行多个方法,而不仅仅是SetTime,我需要创建多个任务吗?当然,您可以添加多个任务,并在每个任务中调用特定的方法。但是,由于它们都将使用相同的共享资源UI,调用请求将排队,而不是立即执行,因此我将坚持使用一个任务,其中可能有多个方法调用。可能有一些逻辑来决定调用哪一个