C# 使用计时器类时获取错误跨线程操作

C# 使用计时器类时获取错误跨线程操作,c#,winforms,datagridview,C#,Winforms,Datagridview,我有一个Winform应用程序,我对它的功能很满意。我希望每15分钟从数据库检索一次最新数据,并将其显示在DataGridView中 我添加了一个计时器类。15分钟后,我可以调用检索和显示数据的方法。我收到错误信息,请参阅附加的屏幕截图 我做错了什么 下面是我的代码: public partial class Form1 : Form { System.Timers.Timer aTimer; public Form1() { InitializeCompo

我有一个Winform应用程序,我对它的功能很满意。我希望每15分钟从数据库检索一次最新数据,并将其显示在DataGridView中

我添加了一个计时器类。15分钟后,我可以调用检索和显示数据的方法。我收到错误信息,请参阅附加的屏幕截图

我做错了什么

下面是我的代码:

public partial class Form1 : Form
{
    System.Timers.Timer aTimer;

    public Form1()
    {
      InitializeComponent();
      StartTimer();
    }

    private void RetrieveData()
    {

      DataTable table = new DataTable();
      table.Rows.Add(woStatus, dateReceived, dateApprovedFormatted, binNo, ppNo, woNo, daysDifference);

      dataGridViewMain.DataSource = table;
      dataGridViewMain.Sort(dataGridViewMain.Columns["Days in the shop"], ListSortDirection.Descending);
    }

    private void StartTimer()
    {
      aTimer = new System.Timers.Timer(10000); // 10secs
      aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
      RetrieveData();
      aTimer.Start();
    }

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
      aTimer.Stop();
      aTimer.Dispose();
      StartTimer();
    }
}

System.Timers.Timer在随机工作线程而不是UI线程上发回。因此,当代码通过OnTimedEvent进入RetrieveData时,StartTimer位于错误的线程上。您可以使用this.InvokeMethodInvoker委托{…}来访问正确的线程,但使用System.Windows.Forms.Timer组件可能更简单,因为它会通过同步上下文在UI线程上自动触发。

System.Timers.Timer会在随机工作线程上触发,而不是在UI线程上。因此,当代码通过OnTimedEvent进入RetrieveData时,StartTimer位于错误的线程上。您可以使用this.InvokeMethodInvoker委托{…}来访问正确的线程,但使用System.Windows.Forms.Timer组件可能更简单,因为它会通过同步上下文在UI线程上自动触发。

我看不到任何屏幕截图,但是如果您遇到跨线程异常,我怀疑这是因为您在StartTimer方法中调用RetreiveData,该方法在计时器线程上调用,当它消失时。您需要确保影响UI的代码与UI在同一线程上执行,否则会出现此类异常。看看invokererequired和Control.Invoke方法,它们用于确保影响UI的方法调用在上下文切换回UI线程后完成

我看不到任何屏幕截图,但如果您遇到跨线程异常,我会怀疑这是因为您在StartTimer方法中调用了RetreiveData,该方法在计时器线程上调用,当它消失时。您需要确保影响UI的代码与UI在同一线程上执行,否则会出现此类异常。看看invokererequired和Control.Invoke方法,它们用于确保影响UI的方法调用在上下文切换回UI线程后完成

看到附加的屏幕截图-我看不到,但我认为我们不需要它。RetrieveData不应该在OnTimedEvent中执行吗?这种轮询可以完成,但实际上不应该完成。数据库更新后,您应该会收到通知,然后查询数据库。请参阅随附的屏幕截图-我看不到,但我认为我们不需要它。在OnTimedEvent中不执行RetrieveData吗?这种轮询可以完成,但确实不应该完成。数据库更新后,您应该会收到通知,然后查询数据库。谢谢。我不知道Windows.Forms中有计时器组件。我觉得这篇文章很有帮助,谢谢。我不知道Windows.Forms中有计时器组件。我觉得这篇文章很有帮助