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.TimerUIスレッドではなく、ランダムなワーカースレッドで再起動します。したがって、コードが( thenRetrieveDataを介して)入ると、間違ったスレッドになります。を使用して適切なスレッドに到達することもできますが、代わりにコンポーネントを使用する方がおそらく簡単です。これは、UIスレッドで自動的に(sync-contextを介して)起動するためです。OnTimedEventStartTimerthis.Invoke((MethodInvoker) delegate {...})System.Windows.Forms.Timer

于 2013-02-22T21:32:24.617 に答える
1

スクリーンショットは表示されませんが、クロススレッド例外が発生した場合は、経過時にタイマー スレッドで呼び出される StartTimer() メソッド内で RetreiveData() を呼び出しているためと思われます。UI に影響を与えるコードが UI と同じスレッドで実行されるようにする必要があります。そうしないと、この種の例外が発生します。InvokeRequired()UI スレッドに戻るコンテキスト スイッチに続いて、UI に影響を与えるメソッド呼び出しが確実に行われるように提供されているメソッドと Control.Invoke() を見てください。

于 2013-02-22T21:34:39.267 に答える