C# 多个Windows.Forms.Timer,应用程序运行缓慢

C# 多个Windows.Forms.Timer,应用程序运行缓慢,c#,winforms,performance,timer,C#,Winforms,Performance,Timer,我的问题是c窗体应用程序中有多个Windows.Forms.Timer时的性能 例如,timerHora的间隔为1秒,在标签中显示当前小时 我没有任何异步方法,因此,当我运行应用程序时,我的GUI不会每秒刷新小时标签,我猜它与其他计时器在同一线程中运行,并等待其他函数完成,因此它有时每秒刷新一次,其他时间为2、3或4秒 所以。。。您能为我推荐处理此问题的最佳做法吗?问题可能是timmers事件太慢。 timmers是在主线程中执行的,因此如果您的代码很慢,那么您将减慢所有表单的速度 尝试使用线程

我的问题是c窗体应用程序中有多个Windows.Forms.Timer时的性能

例如,timerHora的间隔为1秒,在标签中显示当前小时

我没有任何异步方法,因此,当我运行应用程序时,我的GUI不会每秒刷新小时标签,我猜它与其他计时器在同一线程中运行,并等待其他函数完成,因此它有时每秒刷新一次,其他时间为2、3或4秒


所以。。。您能为我推荐处理此问题的最佳做法吗?

问题可能是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,调用请求将排队,而不是立即执行,因此我将坚持使用一个任务,其中可能有多个方法调用。可能有一些逻辑来决定调用哪一个