简体   繁体   English

获取错误使用Timer类时跨线程操作

[英]Getting error Cross-thread operation when using Timer class

I have a Winform application, and I am satisfied with what it does. 我有一个Winform应用程序,我对它的功能感到满意。 I want to retrieve the latest data from the database every 15 minutes and display it in a DataGridView. 我想每15分钟从数据库中检索一次最新数据,并将其显示在DataGridView中。

I added a Timer class. 我添加了一个Timer类。 Once 15 minutes has elapsed, I can call the method that retrieves and displays the data. 15分钟过去后,我可以调用检索和显示数据的方法。 I received error (see the screenshot attached). 我收到错误消息(请参阅所附的屏幕截图)。

What am I doing wrong here? 我在这里做错了什么?

Below is my code: 下面是我的代码:

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 fires back on a random worker thread, not the UI thread. System.Timers.Timer在随机工作线程而不是 UI线程上触发。 So when the code goes into RetrieveData (via OnTimedEvent then StartTimer ) it is on the wrong thread. 因此,当代码进入RetrieveData (通过OnTimedEvent然后通过StartTimer )进入错误的线程时。 You could use this.Invoke((MethodInvoker) delegate {...}) to get to the right thread, but it is probably simpler just to use the System.Windows.Forms.Timer component instead, since that automatically (via sync-context) fires on the UI thread. 您可以使用this.Invoke((MethodInvoker) delegate {...})到达正确的线程,但是使用System.Windows.Forms.Timer组件可能更简单,因为它是自动的(通过sync-上下文)在UI线程上触发。

I don't see any screenshot, but if your getting a cross-thread exception, I'd suspect its because you call the RetreiveData() within the StartTimer() method that's called on the timer thread when it elapses. 我没有看到任何屏幕截图,但是如果您遇到跨线程异常,我会怀疑是因为您在StartTimer()方法内调用了RetreiveData(),而该方法在计时器线程结束时就已调用。 You need to ensure that code affecting the UI is executed on the same thread as the UI, or you will get these kinds of exceptions. 您需要确保影响UI的代码在与UI相同的线程上执行,否则您将获得此类异常。 Take a look at the methods InvokeRequired() and Control.Invoke() that are provided to ensure method calls affecting the UI are done following a context switch back to the UI thread. 看一下提供的方法InvokeRequired()和Control.Invoke(),以确保在上下文切换回UI线程之后完成影响UI的方法调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM