私は数日間マルチスレッドと戦ってきました。
のさまざまな方法がわかりませんmultithreading
。backgroundWorker
スレッドのオブジェクトの作成について少し読みました。昨日delegate
、 を呼び出してマルチスレッドを実装する例を見ましたBeginInvoke
。
multithreading
これらの異なる方法または同じバックグラウンド クラスで同じ作業を行っていることを理解していません。私にそれを明確にするのを手伝ってください。
私は数日間マルチスレッドと戦ってきました。
のさまざまな方法がわかりませんmultithreading
。backgroundWorker
スレッドのオブジェクトの作成について少し読みました。昨日delegate
、 を呼び出してマルチスレッドを実装する例を見ましたBeginInvoke
。
multithreading
これらの異なる方法または同じバックグラウンド クラスで同じ作業を行っていることを理解していません。私にそれを明確にするのを手伝ってください。
私はこの説明がとても好きです。多分彼らもあなたを助けます。
そして、Jon Skeet によるこの記事もあります。
GUI を持たないスレッドはすべてバックグラウンド ワーカーです。ドット ネットでは、スレッドを使用する一般的な方法は、スレッド オブジェクトを作成し、それにスレッドのメイン メソッドを与えることです。そのため、この関数はバックグラウンドで実行されます。この件に関するより深い知識を得るには、次の本を読む必要があると思います。
さらに、WPF や win フォーム アプリなどの GUI アプリでは、GUI 要素を変更できる唯一のスレッドはメイン スレッド (GUI スレッド) であるため、このスレッドを使用して begininvoke を使用し、そこにコールバックを配置して GUI を変更する必要があります。そうしないと、無効な操作の例外が発生します。
スレッドを使用する別の方法は、これらのように.netのスレッドプールを使用することです
ThreadPool.QueueUserWorkItem(new WaitCallback(delegateMethod), data);
private void delegateMethod(object data){
//some stuff
}
まず、どうしても必要な場合を除き、マルチスレッドは使用しないでください。マルチスレッド化の問題を回避できるため、コードを回避して最適化することを最も効果的に行うことが最善の方法です。
次に、BackgroundWorkerクラスは良い出発点です。スレッドの実行に必要な数のインスタンスをインスタンス化する必要があります。それぞれについて、そのDoWork()メソッドをコーディングする必要があります。このメソッドは、 BackgroundWorker.RunWorkerAsync()メソッドを呼び出して操作を開始すると呼び出されます。DoWork() イベントに配置するコードは、アプリケーションのメイン スレッドが他の処理でビジー状態になっている間、バックグラウンドで非同期に実行されるコードです。他の 2 つのイベント: ProgressChanged()とRunWorkerCompleted()は、ReportProgress() に使用されます。または、スレッドがその仕事を終えたときに何をするかを定義するために、それが何であれ(例外、適切に終了するなど)、私はほとんどの場合、BackgroundWorkerをそのまま使用します。使用済み。
3 番目に、 System.Threading.Threadクラスを使用できます。DoWork() イベントを定義し、別のメソッドを呼び出して発生させるよりも少し複雑です。デリゲートと知り合いになる必要があります。つまり、デリゲートは、バックグラウンドで何らかの作業を実行するために使用されるメソッドまたは関数のタイプです。これらのデリゲートに関しては、同じデリゲート タイプのメソッドが複数ある場合があります。先ほど述べたように、デリゲートはメソッド タイプです。デリゲートの参照が複数ある場合があります。メソッド シグネチャとしても表示される場合があります。次に、それを使用するときが来たら、必要なデリゲートのメソッドを参照する必要があります。System.Threading.Thread クラスを使用して、ThreadStart デリゲートに注目します。
delegate void DoWork(object sender);
private void btnProcessWork_Click(object sender, EventArgs e) {
DoWork doWork = SimpleDoWorkMethod;
// Then start using the delegate.
Thread t = new Thread(new ThreadStart(doWork));
t.Start(); // Launch the thread in background...
// Do something else while the thread is working !!!
}
private void SimpleDoWorkMethod(object s) {
// Do some work here...
}
第 4 に、イベントはデリゲートに基づいているため、デリゲートをイベントと考えてください。実際のところ、たとえば Button_Click() などのイベントを処理するために使用されるメソッドを提供します。プログラムで btnProcess.Click イベントを btnProcess_Click() メソッドに関連付けるには、次のように記述する必要があります。
btnProcess.Click += new EventHandler(btnProcess_Click);
ここで行うことは、btnProcess.Click イベントが btnProcess_Click() メソッドを参照するようにすることです。ThreadStart デリゲートを持つ EventHandler デリゲートに注意してください。これらはまったく同じ目的を果たしますが、2 つの異なる現実 (GUI イベント応答とマルチスレッド) を目的としています。
第5に、変数にアクセスする前に変数をロックすることを忘れないでください。別の変数がほぼ同時にアクセスする可能性があります。その後、クロススレッドなどの例外をスローします。これは、プリミティブ型の場合でも、より具体的にはコレクションの場合です。それらはスレッドセーフではありません。
これが少し役立つことを願っています!=)