違いを呼び出し、BeginInvokeメソッド
BeginInvokeメソッドを呼び出すと概念と混沌を使用することで、二日間は、いくつかの情報を見て、これらの2つの原則の使用は、いくつかの新しい知識と理解を持っています。
最初はそれが起動し、2例があるBeginInvokeメソッドを使用して、言いました:
呼び出しの1コントロール、BeginInvokeメソッド。
ボークで2 delegrate、BeginInvokeメソッド。
どちらの状況が異なっている、私たちは第一種の話をするためにここにいます。.NETのと下の用語の正式な定義BeginInvokeメソッドを呼び出し、私たちは以下に。
control.invoke(パラメータデリゲート)メソッドは:持っているこのコントロールのウィンドウハンドルの基礎となるスレッド上で実行するために指定したデリゲートを。
control.begininvoke(パラメータデリゲート):で作成スレッド上でそのコントロールの基になるハンドルの非同期実行、指定したデリゲート。
これら二つの概念の私達の一般的な理解によると、テーブルがされている起動同期 BeginInvokeメソッドを表し、非同期。しかし、どのようにそれを同期および非同期するには?私たちは、テストを行います。
呼び出し例:
プライベートボイドのbutton1_Click(オブジェクト送信者、のEventArgs e)の { MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+ " AAA " )。invokeThread = 新しいスレッド(新しいThreadStart(StartMethod)); invokeThread.Start(); 列A = 文字列.Empty。ため(I = int型、iは<0 3; iは++)// 调整循环次数、看的会更清楚{のThread.sleep(1000年)。= A + " B " 。} MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+ A)。} プライベートのボイドStartMethod(){MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+。" CCC " )。button1.Invoke(新しいinvokeDelegate(は、invokeMethod)); MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+。" DDD " )。} プライベートボイドは、invokeMethod(){ // のThread.sleep(3000); MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+。" EEE " )。}
結論:我々は実行し、実行シーケンスfacieプログラム、1AAA-> 3CCCと> 1EEE 1BBB- - > 3DDD。
説明:メインスレッドは、メソッドの実行が完了するは、invokeMethodうまで1AAA、同時に実行後、1BBBと子スレッド3CCC、その後、呼び出しを介してメインスレッドには、invokeMethodメソッドを提出し、メインスレッドの実行のために、子スレッドの待機を実行しているメインスレッドがメインスレッドを待たなければなりません(中タスクの実行が完了すると、ミッションは)提出を呼び出すために行くだろう、最後のサブスレッドの実行3DDD。
BeginInvokeメソッドの例:
プライベートボイドのbutton1_Click(オブジェクト送信者、のEventArgs e)の { MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+ " AAA " )。invokeThread = 新しいスレッド(新しいThreadStart(StartMethod)); invokeThread.Start(); 列A = 文字列.Empty。ため(I = int型、iは<0 3; iは++)// 调整循环次数、看的会更清楚{のThread.sleep(1000年)。= A + " B " 。} MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+ A)。} プライベートのボイドStartMethod(){MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+。" CCC " )。button1.BeginInvoke(新しいinvokeDelegate(は、invokeMethod)); MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+。" DDD " )。} プライベートボイドbeginInvokeMethod(){ // のThread.sleep(3000); MessageBox.Show(Thread.CurrentThread.GetHashCode()のToString()+。" EEEEEEEEEEEE " ); }
結論:1AAA-> 1BBBと3CCC-> 1EEEと3DDD:我々は、操作を行った後の結果を参照してください。
その後、1AAA、その後、1BBBと同時に実行子スレッド3CCCを実行しているメインスレッド、およびBeginInvokeメソッドを介してメインスレッドには、invokeMethodメソッドを提出し、その後、メインスレッドの実行1EEE(そのタスクの実行が完了すると、メインスレッド)、子スレッドが3DDDを継続する一方で:説明。
2つのテストにこのコードを比較することによって、私たちは、実際にデリゲートメソッドを呼び出し、BeginInvokeを提出したことがわかりますメインスレッドで実行され、実際には、私の定義によれば、我々は、ビューのサブスレッドで、この問題にBeginInvokeメソッドを呼び出すと、私たちは、デリゲートメソッドが送信実行がDDDに進む前に、完了している呼び出すことがわかり例を呼び出し、BeginInvokeメソッドの例の後に我々はデリゲートメソッドは、BeginInvokeを提出したことがわかり、子スレッドはデリゲートメソッドの完了を待たずに、DDDを続け伝えます。だから今我々は(同期)の概念とBeginInvokeメソッド(非同期)を呼び出すために戻って考えて、実際に彼らがコントロールを呼び出すために、実際には、子スレッドへの相対的な用語の意味は常にメインスレッドで実行されます。私たちの多くは、私たちが間違った参照を持っている主な理由は、同期および非同期を混乱させる。実際には、時々ちょうど概念を見てすることは間違って理解しやすいです。
これは、アクセス制御スレッドを解決するために作成されていませんでした
マルチスレッドプログラミングでは、私たちはしばしば、複数のスレッドで直接画面表示を更新するために、スレッドを動作させる必要があり、およびメソッド呼び出しインターフェースコントロール間違ったアプローチであるあなたがよりになるように、起動およびBeginInvokeメソッドは、発生し、この問題を解決することです表示を更新するための安全なインターフェースを通します。
正しいアプローチは、スレッドが2つの間の差が生じる、呼び出す呼び出しまたはBeginInvokeをによる方法、としてパッケージインタフェース・コードの更新を必要とする仕事にある他方はないが、待機するワーカースレッドです。
いわゆる「サイド・レスポンスアクション、側ノードの追加」インタフェースは、常にUIスレッドを経由してアップデートを行う権利であるからしか、唯一のUIスレッド上の負担のあまりをしないように、相対することができ、我々はで物事を行う必要がありますワーカースレッドが操作のほとんどを席巻し、UIスレッド上の負担を軽減する目的を達成するそうするように、純粋なインタフェースUIスレッドに更新されます。
ここでは簡単な例は、あなたがスレッドを開始するなどの方法を用いた場合を例示している、テキストボックスには、スレッドの方法でフォームを更新したいです。..
System.Threading使用;
//スレッド開始
スレッドスレッドは=新しい新しいスレッド(新しい新しいThreadStart(DoWorkを));
Thread.start();
//スレッド方式
のプライベートボイドDoWork()
{
this.TextBox1.Textは=「私はテキストですボックス「;
}
あなたはVS2005や異常では2008年に上記の動作を、好きなら...があるでしょう
適切なアプローチが起動\ BeginInvokeメソッドを使用することです
System.Threadingを使用して、
テストを名前空間
{
パブリック部分クラスをForm1:フォーム
{
パブリックデリゲートのボイドMyInvoke (STR1文字列、文字列STR2);
公共のForm1()
{
のInitializeComponent();
}
公共ボイドDoWork()
{
MyInvoke = MI新しい新しいMyInvoke(UpdateForm)。
this.BeginInvoke(MI、新しいオブジェクト[] { "我是文本框"、 "母"})。
}
公共ボイドUpdateForm(文字列PARAM1、ストリングPARM2)
{
this.textBox1.Text = PARAM1 + PARM2。
}
プライベートボイドのbutton1_Click(オブジェクト送信者、のEventArgs電子)
{
スレッドスレッド=新しいスレッド(新しいThreadStart(DoWork))。
thread.Start();
}
}
}
注意代理的使用!
補足後で再び
ようにテキストボックスのTextプロパティを設定し:Winフォーム開発プロセスにおいてしばしば時にはしばしばなどスレッド、スレッドに外部アクセス制御を必要とする、スレッドを使用します。代わりに、スレッドの制御からのアクセス、それを作成するのではなく、例外:セットアッププログラムは、確かに直接の引用れます。通常、我々は解決するために2つのメソッドを使用することができます。まず、コントロールのプロパティを設定することもできます。第二に、デリゲートを通じて、他は匿名である一方、1は、一般的な方法である、二つの方法によっても委任します。それは、それぞれ、以下に説明します。
解決しました。まず、プロパティの値がfalseで設定することで、私たちは制御のForm_Load方法:. Control.CheckForIllegalCrossThreadCalls = falseを追加することができます。falseに設定するには、コールが間違ったスレッドをキャプチャしていないことを示しています。テキストボックスのTextプロパティは、もはやエラーを設定しますスレッドでそう。第二に、メソッドのデリゲートによって解決されます。以下のような一般的なデリゲートメソッド:
委任無効SafeSetText(文字列strMsgを)。 プライベートボイドのsetText(文字列strMsg){ 場合(textbox1.InvokeRequired){SafeSetText objSet = 新しいSafeSetText(のsetText)。textbox1.Invoke(objSet、新しいオブジェクト[] {strMsg})。} 他{textbox1.Text = strMsg。}}
あなたがスレッドでテキストボックスの値を設定する必要がある場合のsetTextメソッドを呼び出すことができます。我々はまた、達成するために委託する別の方法を使用することができ、それは例えば、匿名プロキシです。
委任無効SafeSetText(文字列strMsgを)。 プライベートボイドSetText2(ストリングstrMsg){SafeSetText objSet = デリゲート(文字列strの){textBox1.Text = STR。} textBox1.Invoke(objSet、新しいオブジェクト[] {strMsg})。}
また、これは達成されます。個人的に私はそれが薬の有効活用だと思います。
ラムダ式では、このような上記の匿名の代表者としてではC#3.0以降のバージョンでは、より簡潔な表現を持っています。.NET Frameworkの3.5またはそれ以上のアクションの包装方法とそれ以降のバージョン。たとえば、以下の文言は非常に単純に見えるかもしれません。
無効ButtonOnClick(オブジェクト送信者、EventArgsの電子)
{
this.Invoke(新しいアクション(()=>
{
button.Textは= "OFF";
}))。
}
https://www.cnblogs.com/lsgsanxiao/p/5523282.html