2014-10-11 1 views
0

BackgroundWorker은 UI 컨트롤에 직접 액세스 할 수 있지만 Thread은 불가능합니다. 이유가 무엇입니까?스레드는 UI 컨트롤에 액세스하려면 Invoke 메서드를 사용해야하지만 BackGroundworker는 UI 컨트롤에 액세스하지 않아야합니다. 왜?

BackgroundWorker가 스레드가 아닙니까? 그렇지 않다면 무엇입니까? 또한 직접 액세스가 제한되는 이유는 무엇입니까? 무언가를하기위한 Microsoft의 선택 방법에 대한 직접 액세스를 제한하고 있습니까? 그렇지 않으면이 방법으로해야합니까?

답변

-1

백그라운드 작업자는 새 스레드와 마찬가지로 크로스 스레드 예외를 발생시킵니다. 배경 작업자는 새 스레드를 시작하는 멋진 방법입니다.

ProgressChanged 이벤트를 사용하는 경우 장면 뒤에서 .NET 마술이 있기 때문에 호출 할 필요가 없습니다. 배경 노동자

더 많은 정보 : http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.100).aspx

+0

나는 "일부 .NET 마술"이라고 부르지 않을 것입니다. 단지 Invoke 호출 일뿐입니다. –

1

MSDN에 따르면, "이 BackgroundWorker 클래스는 별도의 전용 스레드에서 작업을 실행할 수 있습니다."

BackgroundWorkerForm.Invoke()을 사용하면 제어를 주 UI 스레드로 전환하여 진행 상황을보고 할 수 있습니다. 사실 BackgroundWorker은 자신을 쉽게 작성할 수있는 도우미 클래스 일뿐 아니라 두 번째 스레드를 사용하여 작업을 수행하지만 GUI에 액세스하기 위해 기본 UI 스레드로 전환합니다.

또한 MSDN에서 : "작업 진행 상황을보고하고 작업 완료시 신호를 보내는 이벤트를 수신 할 수 있습니다." 이는 백그라운드 작업이 별도의 스레드에서 실행되며 해당 스레드에서 GUI에 액세스 할 수 없음을 의미합니다. 그러나 UI UI 스레드에서 발생하기 때문에 진행 이벤트에서 GUI 컨트롤에 액세스 할 수 있습니다. 작업자 스레드에서 BackgroundWorker.ReportProgress()을 호출 할 때마다 주 스레드에서 BackgroundWorker.ProgressChanged 이벤트가 발생합니다.

또한 다른 스레드에서 GUI에 액세스 할 수없는 이유를 묻습니다. 전체 Windows GUI 하위 시스템이 스레드로부터 안전하지 않기 때문입니다. 필자가 아는 한, 이것은 다른 플랫폼 (Windows 외부)에서도 꽤 정상적이므로 마이크로 소프트에만 국한된 것은 아닙니다. 아마도 역사적인 이유로 아마 코드 효율성과 관련이 있습니다. (스레드 안전 GUI는 느려질 것입니다.) 그러나 나는 어떤 강력한 정보 소스를 참조로 제공 할 수 없습니다.

+1

SynchronizationContext.Post()를 사용하기 때문에 여전히 WPF에서 작동합니다. –

+0

@AlKepp 맞습니까? Backgroundworker를 사용하지 않고 가능한 모든 속성 변경에 대한 메서드 대리자를 정의해야합니까? 그것은 미친 짓이야! Backgroundworker를 사용하지 않고이 작업을 수행하는 간단한 방법이 있습니까? – camadan

+0

@camadan : Control.InvokeRequired()는 GUI에서 변경되는 모든 메서드에서 사용할 수 있습니다. InvokeRequired가 true를 반환하면 Invoke를 사용하여 메서드가 주 스레드에서 자신을 호출하게합니다. –