2016-09-08 14 views
0

長時間実行中のルーチンで頻繁に更新する単純なステータスラベルがあります。ルーチンはタイマー上にあり、したがって別のスレッド上にあるので、私はCross-thread operation not validエラーを受け取ります。私はこのようなSOの修正を見つけました:毎回呼び出さずに別のスレッドによって作成されたオブジェクトにアクセスしますか?

lblQuery1Status.Invoke(new Action(delegate 
{ 
    lblQuery1Status.Text = "Status: Publishing"; 
})); 

しかし、このコントロールのテキストをルーチン中に7回または8回更新します。これを行うためのより効率的な方法や簡単な方法がありますか?

+2

それについては何が非効率ですか? 7〜8回する必要がある場合は、statusを文字列入力と呼ぶメソッドに貼り付けます。私はあなたの代理人を見ています。私は本当にsnarkyになろうとしていません - あなたが効率的だと言うときにあなたがコミュニケーションしているものについて興味があるのですか? –

+0

私はそれにアクセスする必要があるたびに新しいスレッドで1回呼び出すことができるかどうか疑問に思っています。私は '.net'と特にスレッド化するのが初めてです。 –

答えて

3
大丈夫だと思い秒でそれを呼び出している場合を除き

あなたは構文の「簡素化」したい場合は、必ず構文を「短く」するためにインラインラムダを使用することができます。

lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing")); 

必要な時はいつでもあなたはまた、呼び出しのための行動変数と再起動アクションを作成することができます:

Action updateStatus =() => 
    lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing")); 

その後、必要に応じて法何度でもそれを呼び出すことができます。

updateStatus(); 
+0

はい、私は 'invoke'が新しいスレッドを作成していないことを知っていました。新しいスレッドを一度*呼び出す方法があったと思っていましたが、その後に何度も参照していました(毎回呼び出さずに) –

+0

@Scottああ、私の間違い。最後の更新は、あなたが探しているものに近いものになりますか? –

+0

間違いなく、アクションハンドルが面白そうです。私はそれを研究します。ありがとう。 –

0

それがUIスレッドへのあなたの実行時間の長いタスク/スレッドからデータを取得するための最良の方法だUnfortunatley、マーシャリングは、そのオーバーヘッドを持っていますが、何百回も私はあなたが

1

これは私が@David Lさんanswer aboveに基づいて、一緒に行ったソリューションです。

アクションの定義:

Action<string> updateStatus = (s) => 
    statusLabel[qo.id].Invoke(new Action(() => statusLabel[qo.id].Text = s)); 

コール:

updateStatus("Opening Connection"); 

私はそれは、より効率的だが、それははるかに簡単かつきれいだし、それは私があまりをうんざりになり実現しません。

関連する問題