2011-03-16 2 views
1

Silverlight에서는 this.Dispatcher.BeginInvoke((ThreadStart)delegate(){})을 사용하는 UI 스레드에 대한 호출을 마샬링합니다.Dispatcher.BeginInvoke C#, silverlight

내 질문은 여러 스레드가 다음이 호출을 수행하는 함수를 호출하는 경우 대기열에 넣고 차례로 실행합니까? 그렇다면 함수가 여러 스레드에서 호출 되더라도 this.Dispatcher.BeginInvoke((ThreadStart)delegate(){}); 안의 코드는 스레드로부터 안전하다는 것을 안전하게 가정 할 수 있습니까?

+0

위임자와 그 함수가 호출하는 것은'BeginInvoke'를 통해서만 호출된다는 것이 정확해야한다고 생각합니다. –

답변

3

코드는 상태가없는 경우 스레드로부터 안전하며 스레드 경계를 넘어 공유 할 수있는 상태를 수정하거나 스레드 안정성을 보장하기 위해 해당 주 사용자가 공유하는 제어 된 방식으로 상태를 수정합니다 (예 : 잠금 장치).

따라서 스레드 안전성은 Dispatcher.BeginInvoke에서 보장 할 수 없습니다. 즉, 위임자는 모두 동일한 스레드 (UI 스레드)에서 실행되므로 대리인이 동시에 실행되지 않는다고 가정 할 수 있습니다. 그렇다고해서 위임자가 수행하는 작업에 따라 스레드 안전성이 보장되는 것은 아닙니다. 그러나 위임자가 호출 한 위임자 또는 메서드의 다른 스레드를 회전하거나 상호 작용하지 않으면 스레드 안전성을 가정 할 수 있습니다.

+1

바로 알겠습니다.사실 BeginInvoke 대리자 내부의 데이터 구조에 액세스하고 있는데 동시에 비 UI 스레드가 액세스 할 수 있으므로 동기화해야한다는 것을 알고 있습니다. 나는 지금이 점에 분명하다고 생각합니다. 대답 한 모두에게 감사드립니다. – user642770

0

예, 이러한 호출은 대기 상태가됩니다. BeginInvoke에 대한 호출은 스레드로부터 안전합니다 (언제든지이 메서드를 모든 스레드에서 호출 할 수 있음). UI 스레드에 마샬링 된 모든 호출은 모두 단일 스레드로 실행됩니다. 단 하나의 UI 스레드가 있기 때문입니다. 때문에.

+0

실제로는 스레드로부터 안전하지는 않습니다. 개체를 참조하고 충돌을 일으키는 배경 스레드를 쉽게 가질 수 있습니다. UI 스레드에서 모든 작업을 수행하면 한 번에 하나의 대리자 만 실행할 수 있지만 스레드로부터 안전하지는 않습니다. –

+0

@justin'BeginInvoke' *에 대한 호출은 스레드로부터 안전합니다. 그건 당신 코드가 있다는 것을 의미하지 않는다. – Will

+0

하, 좋은 지적. 그건 사실입니다. –

0

일반적으로 네, 각 대리인이 큐에 추가되어 Dispatcher 스레드의 처리를 기다리는 것이 맞습니다.

Dispatcher.BeginInvoke() 호출에서 대리인 호출에 대한 현재 또는 향후 보증이 있는지 확실하지 않지만 현재 주문이 보존 된 것 같습니다.

그렇지만 Dispatcher (UI) 스레드 만 있다고 가정하는 것이 안전하므로 여러 대의 대리인이 동시에 호출되지 않습니다.

1

코드 스 니펫은 (ThreadStart) 대리자 형식을 사용하기 때문에 오도 된 것입니다. 중요한 것은 모든 STA 스레드 환경에서 정확히 하나의 스레드가 "UI"스레드라는 점입니다. 모든 UI 객체는 해당 스레드에서 생성되고 상호 작용되어야합니다.

Dispatcher는 몇 가지 용도로 사용되므로 가장 쉽게 이해할 수있는 사용법은 백그라운드 스레드에서 사용하여 UI 스레드로 다시 호출하는 것입니다. 그래서 거기에 넣는 것은 정확히 "스레드 안전"이 아니지만 UI 스레드에서 호출되도록 보장됩니다. UI 스레드에 모든 것을 넣으면 동시에 호출되는 것이 아니라 차례로 호출됩니다.

BeginInvoke는 Invoke가 동기 호출 인 동안 UI 스레드 큐에 대리자를 넣는 비동기 호출입니다. 정말로 놀라운 점은 차단할 UI 스레드에서 실제로 Invoke를 호출 할 수 있고 대리인을 대기열에 넣고 대기열의 다음 항목으로 이동하여 결국에는 호출 한 항목을 호출한다는 것입니다.

Dispatcher는 실제로 우선 순위 대기열이라는 점을 명심해야합니다. 따라서 선입 선출의 의미에서 순수한 대기열이 아닙니다. 왜냐하면 여러분이 대기열에 삽입 된 곳이 우선 순위에 기반을두고 있기 때문에 호출 된 메소드가 결코 실행되지 않는 충분한 것들이 대기열에 끼어들 가능성이 완전히 있기 때문입니다 .