2012-07-03 2 views
14

C#에서 개발하는 동안이 문제를 여러 번 경험했습니다. 나는 행복하게, 함께 코딩 이리저리 스레드와 어떤 사이에 물체를 통과 할 것없는, 모든 나는이 익숙 오류 얻을 갑자기 :일부 개체가 다른 스레드에서 액세스 할 수없는 이유는 무엇입니까?

"The calling thread cannot access this object because a different thread owns it."

음, 좋아, 내가 전에 그것을 처리 한을, 특히 GUI 스레드에있는 객체의 경우 특정 문제를 해결하기 위해 몇 가지 추가 코드를 작성하면됩니다. 그러나 매번 나는 평범한 대상을 보았지만 다른 스레드가 액세스하는 것을 좋아하지 않습니다.

EDIT 액세스 예외를 일으키는 개체에 대한 원래 게시물에서 오인되었습니다. 그것은 IPAddress이 아니고 대신 IP 주소를 얻기 위해 사용했던 System.Printing.PrintQueue.입니다. 이것은 하나 이상의 스레드에서 평가할 수없는 개체입니다.

내가 작성한 모든 수업에는이 문제가 없습니다. 나 자신을 어떻게 구현할 지조차 모른다. 당신이 만든 스레드 ID로 멤버 변수를 유지하고 모든 단일 속성 및 메서드 액세스에 대해 현재 스레드를 확인해야합니까? 그게 미친 것 같아. 왜 마이크로 소프트는 ..... "OK ... PrintQueue, 확실히 스레드 사이에서 공유 할 수 없다고 결정할 것입니다.하지만이 다른 클래스는 ...."

왜 일부 개체는 여러 스레드 액세스가 차단 되었습니까?

+2

대안에 대해 생각해보십시오. 모든 스레드는 원하는대로 모든 개체에 액세스 할 수 있습니다. 이제는 객체가 스레딩 문제를 적절히 처리하기 위해 접근 자에 의존해야하거나 여러 스레드의 접근 자에게 안전하도록 여러 가지 코드를 작성해야합니다. 옵션 1은 현실적이지 않고 옵션 2는 많은 작업입니다. 그래서 옵션 3 : 여러 스레드의 접근자를 허용하지 않기로 결정했습니다. – dlev

+1

나쁜 마이크로 소프트. 나쁜. –

+1

C# 가비지 처리는 사용 방법에 따라 특정 변수를 잠급니다. 필자는이 문제를 다루지 않았지만이 문제를 해결하는 좋은 방법은 스레드간에 공유 할 계획이라면 변수를 정적 소유자로 두는 것입니다. 하나의 스레드는 다른 스레드 쓰기를 읽습니다. 둘 다 값을 변경해야하는 경우 쓰기에 충돌이 없도록 잠금을 수행해야 할 수도 있습니다. –

답변

3

이것은 상당히 잘 설명 할 수 있다고 생각하는데, 이는 구체적으로 COM과 관련이 있다고 생각합니다. 구체적

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

.

In general, the simplest way to view the COM threading architecture is to think of all the COM objects in the process as divided into groups called apartments. A COM object lives in exactly one apartment, in the sense that its methods can legally be directly called only by a thread that belongs to that apartment. Any other thread that wants to call the object must go through a proxy.

There are two types of apartments: single-threaded apartments, and multithreaded apartments.

Single-threaded apartments consist of exactly one thread, so all COM objects that live in a single-threaded apartment can receive method calls only from the one thread that belongs to that apartment. All method calls to a COM object in a single-threaded apartment are synchronized with the windows message queue for the single-threaded apartment's thread. A process with a single thread of execution is simply a special case of this model.

Multithreaded apartments consist of one or more threads, so all COM objects that live in an multithreaded apartment can receive method calls directly from any of the threads that belong to the multithreaded apartment. Threads in a multithreaded apartment use a model called free-threading. Calls to COM objects in a multithreaded apartment are synchronized by the objects themselves.

+2

System.Printing.PrintQueue 개체가 실제로 STA COM 개체라는 것을 의미합니까? 그리고 다른 스레드가이 인터페이스를 사용할 수없는 이유는 무엇입니까? System.Printing.PrintQueue 문서를 보면 STA COM 개체라는 것을 어떻게 알 수 있습니까? – Ultratrunks

+0

재미있는 것들. 나는 이것이 http://msdn.microsoft.com/en-us/library/5s8ee185.aspx가 위의 답을 보완한다고 생각한다. (왜 Ultratrunks가 GUI 프로그래밍과 관련하여 그러한 문제를 겪었는지 설명한다.) – jpe

+0

@Ultratrunks 인쇄 대기열에 액세스하기 때문에 클래스가 COM 래퍼라는 것이 확실합니다. 그러나 나는 STA가 무엇인지를 어떻게 알 수 있을지 모른다. MSDN의 클래스에 대한 스레드 안전 섹션이 있지만 거기에서 볼 것으로 예상되는 내용을 보지 못했습니다. –

관련 문제