1

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

我添加了一个 Timer 类。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();
    }
}
4

2 回答 2

7

System.Timers.Timer触发随机工作线程,而不是UI 线程。因此,当代码进入RetrieveData(通过OnTimedEventthen StartTimer)时,它位于错误的线程上。您可以使用它this.Invoke((MethodInvoker) delegate {...})来找到正确的线程,但仅使用该System.Windows.Forms.Timer组件可能更简单,因为它会自动(通过同步上下文)在 UI 线程上触发。

于 2013-02-22T21:32:24.617 回答
1

我没有看到任何屏幕截图,但是如果您遇到跨线程异常,我会怀疑这是因为您在计时器线程上调用的 StartTimer() 方法中调用了 RetreiveData() 。您需要确保影响 UI 的代码在与 UI 相同的线程上执行,否则您将遇到此类异常。查看提供的方法InvokeRequired()和 Control.Invoke() 以确保影响 UI 的方法调用在上下文切换回 UI 线程后完成。

于 2013-02-22T21:34:39.267 回答