14

C# での開発中に、この問題に何度か遭遇しました。私は喜んでコーディングを行い、オブジェクトをスレッド間で行ったり来たりさせたりしていると、突然、おなじみのエラーが発生します。

「別のスレッドが所有しているため、呼び出しスレッドはこのオブジェクトにアクセスできません。」

そうですね、特に GUI スレッド上のオブジェクトについては、以前に扱ったことがあります。その特定の問題に対処するためのプログラムを作成するために、追加のコードを作成する必要があります。しかし、どうしても普通のオブジェクトに出くわすたびに、それは別のスレッドからアクセスされるのが好きではありません。

編集アクセス例外を引き起こしたオブジェクトに関する元の投稿で、私は間違っていました。IPAddressではなく、System.Printing.PrintQueueでした。IPアドレスを取得するために使用していました。これは、複数のスレッドから評価できないオブジェクトです。

私が書いたすべてのクラスには、この問題はありません。これを自分で実装する方法さえわかりません。自分を作成したスレッド ID を持つメンバー変数を保持し、プロパティとメソッドにアクセスするたびに現在のスレッドを確認する必要がありますか? それはクレイジーに思えます。Microsoft がそう判断した理由は ..... 「わかりました... PrintQueue は、スレッド間で共有できません。しかし、これらの他のクラスは....準備ができています。」

一部のオブジェクトが複数のスレッド アクセスからブロックされるのはなぜですか?

4

1 に答える 1

3

これは物事をかなりうまく説明できると思います。これは特にCOMと関係があると思います。

http://msdn.microsoft.com/en-us/library/ms693344%28v=vs.85%29

具体的には。

一般に、COMスレッドアーキテクチャを表示する最も簡単な方法は、プロセス内のすべてのCOMオブジェクトをアパートメントと呼ばれるグループに分割されていると考えることです。COMオブジェクトは、そのメソッドがそのアパートメントに属するスレッドによってのみ合法的に直接呼び出されるという意味で、正確に1つのアパートメントに存在します。オブジェクトを呼び出したい他のスレッドは、プロキシを経由する必要があります。

アパートには、シングルスレッドアパートとマルチスレッドアパートの2種類があります。

シングルスレッドアパートメントは正確に1つのスレッドで構成されているため、シングルスレッドアパートメントに存在するすべてのCOMオブジェクトは、そのアパートメントに属する1つのスレッドからのみメソッド呼び出しを受け取ることができます。シングルスレッドアパートメントのCOMオブジェクトへのすべてのメソッド呼び出しは、シングルスレッドアパートメントのスレッドのWindowsメッセージキューと同期されます。単一の実行スレッドを持つプロセスは、このモデルの特殊なケースにすぎません。

マルチスレッドアパートメントは1つ以上のスレッドで構成されているため、マルチスレッドアパートメントに存在するすべてのCOMオブジェクトは、マルチスレッドアパートメントに属する任意のスレッドから直接メソッド呼び出しを受け取ることができます。マルチスレッドアパートメントのスレッドは、フリースレッドと呼ばれるモデルを使用します。マルチスレッドアパートメント内のCOMオブジェクトへの呼び出しは、オブジェクト自体によって同期されます。

于 2012-07-03T19:15:47.683 に答える