2011-12-16 11 views
5

私は、自分のウィンドウのフォームで10秒間タイマーを設定しています。 OnTimedEventの場合は、時間が経過した後にフォームが破棄されるように設定されています。しかし、タイマーでフォームを処理するクロススレッドエラー

のエラーがあるようです。InvalidOperationExceptionがユーザーコードによって処理されませんでした。

クロススレッド操作が無効です:作成されたスレッド以外のスレッドからコントロール 'notificationForm'がアクセスされました。

エラーがライン上

protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

だった私のタイマーイベントのコードは、誰もがこの問題を解決する方法を知っている

private void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     this.Dispose(); 
    } 

のですか?ありがとう!

答えて

4

System.Timers.Timerを使用しているようです。

代わりにSystem.Windows.Forms.Timerを使用して、Tickイベントに登録してみてください。

あなたはタイマーは、あなたがこのようにコードを変更してみてくださいことができることを使用する必要がある場合:

private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    this.BeginInvoke((MethodInvoker)delegate { this.Dispose(); }); 
} 
+0

HIであるので、これは動作します。あなたの返事に感謝します。ちょうどwanaが知っている、system.windows.form.timerと通常のタイマーとの違いは何ですか? – Thomas

+1

Timers.Timerはサーバーベースのタイマーです。これは、フォームとは異なるスレッド上にある理由です。 WindowsのタイマーはGUIと同じスレッド上で実行されます。これがwinformsアプリケーションでは一般に使用するより適切なタイマーです。 ToolBoxのタイマーはForms.Timerです。 – LarsTech

1

それとも:

this.Invoke((Action)(() => { this.Dispose(); })); 

あなたは1行で行うことができます。

timer1.Tick += (_, __) => { this.Invoke((Action)(() => { this.Dispose(); })); }; 
1

他の人が述べたように、問題はあなたのタイマーがスレッドを実行していて、crだったオブジェクトを処分しようとしていることです別のスレッドで食べたフォームにアクセスする前にフォーム上で呼び出すには、disposeメソッドが必要です。

基本的には、デザイナーで作成したプレゼンテーションオブジェクトを別のスレッドから変更しようとすると、呼び出しが必要かどうかを確認する必要があります。

void OnTick() 
{ 
    if (InvokeRequired) 
     Invoke(new MethodInvoker(OnTick)); 
    else 
    { 
     Dispose(); 
    } 
} 
2
private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    this.Invoke(new Action(() => this.Dispose())); 
} 

それは