我有一个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();
}
}
答案 0 :(得分:7)
System.Timers.Timer
重新启动随机工作线程,不 UI线程。因此,当代码进入RetrieveData
(通过OnTimedEvent
然后StartTimer
)时,它就是错误的线程。您可以使用this.Invoke((MethodInvoker) delegate {...})
来获取正确的线程,但是使用System.Windows.Forms.Timer
组件可能更简单,因为它会自动(通过sync-context)在UI线程上触发。
答案 1 :(得分:1)
我没有看到任何屏幕截图,但如果你得到一个跨线程异常,我会怀疑它,因为你在StartTimer()方法中调用RetreiveData(),它在定时器线程上被称为 当它过去的时候。您需要确保影响UI的代码在与UI相同的线程上执行,否则您将获得这些异常。查看提供的方法InvokeRequired()
和Control.Invoke(),以确保在上下文切换回UI线程后完成影响UI的方法调用。