2013-01-17 3 views
34

をしてください使用しますはどのようにあなたは私のためにこれを説明してもらえBeginInvokeメソッドのC#

someformobj.BeginInvoke((Action)(() => 
{ 
    someformobj.listBox1.SelectedIndex = 0; 
})); 

あなたは、私がbegininvoke正確にどのように使用できるかを教えてもらえますか? Actionタイプとは何ですか? 空白の括弧があるのはなぜですか()? これはどういう意味ですか=>

+2

1つの投稿に多くの異なる質問があります... - 少なくとも3つの別々の質問があります – Prokurors

+0

http://mark-dot-net.blogspot.com.uy/2014/07この記事もご覧ください/six-ways-to-initiate-tasks-on-another.html –

答えて

57

Actionは、.NETフレームワークが提供する代表者の一種です。 Actionは、パラメータを持たないメソッドを指し、値を返しません。

() =>lambda expressionです。ラムダ式の型はDelegateではありません。呼び出しはDelegateのでActionは、ラムダ式をラップし、期待TypeからInvoke()

Invoke原因はActionは、コントロールのウィンドウハンドルを作成したスレッド上で実行するといわ提供するために使用することができるが必要です。 Exceptionsを避けるには、しばしばスレッドを変更する必要があります。たとえば、最初にInvokeを呼び出さずに、Invokeが必要なときにRichTextBoxRtfプロパティを設定しようとすると、Cross-thread operation not valid例外がスローされます。 Invokeを呼び出す前にControl.InvokeRequiredを確認してください。

BeginInvokeは、Invokeの非同期バージョンです。非同期とは、ブロックしている同期呼び出しとは対照的に、スレッドが呼び出し元をブロックしないことを意味します。

+0

Thannk u very much :)を追加しました。 –

+0

これを正しく理解すれば、スレッド間の安全を保証するためにActionが使用されるため、値を自分で設定する代わりにメソッド呼び出しを通じてオブジェクトに通知します。 また、このメソッドは、アクションだけでなく、代理人も受け入れます。 –

+4

@KyleBaran - 'Action'はスレッドの安全性とは無関係です。つまり、' Invoke'です。 'Invoke'はパラメータとして' Delegate'を受け入れます。したがって、 'Delegate'に変換可能なものはどれもパラメータとして渡すことができます。 –

9

あなたのコードはWindowsフォームに関係すると思います。
UIスレッドで何かを非同期に実行する必要がある場合は、BeginInvokeを呼び出します。ほとんどの場合、コントロールのプロパティを変更します。
大まかに言うと、これは、デリゲートを定期的に実行されているいくつかのプロシージャに渡すことで達成されます。 (メッセージループ処理とそのようなもの)

Delegateタイプの場合はBeginInvokeが呼び出された場合、デリゲートは単に非同期に呼び出されます。
(同期バージョンInvoke。)

あなたがWPFとWinFormsのために完璧に動作し、より普遍的なコードをしたい場合は、タスク並列ライブラリと応じcontextTaskを実行することを検討することができます。 (TaskScheduler.FromCurrentSynchronizationContext()

もう少し先に述べたように追加してください: Lambdasは匿名メソッドまたはexpressionsとして扱うことができます。
それで、lambdasでvarを使うことはできません:コンパイラはヒントが必要です。

UPDATE:

これは、あなたが他のスレッドからタスクを開始した場合の.Net v4.0と高い

// This line must be called in UI thread to get correct scheduler 
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext(); 

// this can be called anywhere 
var task = new System.Threading.Tasks.Task(() => someformobj.listBox1.SelectedIndex = 0); 

// also can be called anywhere. Task will be scheduled for execution. 
// And *IF I'm not mistaken* can be (or even will be executed synchronously) 
// if this call is made from GUI thread. (to be checked) 
task.Start(scheduler); 

を必要とし、そのcompletition task.Wait()を待つ必要までスレッドを呼び出すブロックしますタスクの終了。

タスクhereについて詳しく読む。

+0

私にいくつかの例を教えていただけますか? –

+0

@MohammedNoureldin私はいくつかのコードを –

関連する問題