2009-02-26 2 views
0

.NET에서 Control.Invoke (대리자)를 사용하여 컨트롤에서 작업을 수행해야한다는 것을 알고 있습니다. 이로 인해 Invoke가 실제로 필요한 환경이 무엇인지 궁금하게 생각하게되었습니다. 필자가 아는 한, Visual Basic과 Pascal의 구버전에서는 필요하지 않았다. 특히 Java의 상태 (버전에 따라 다를 수 있음)와 "구식"Windows GUI 프로그래밍 (수동으로 메시지 대기열 읽기)은 무엇입니까?GUI 작동을 위해 호출되는 언어/플랫폼은 무엇입니까?

답변

1

대부분의 언어에서 GUI 작업을위한 호출이 필요합니다. 자바에서는 SwingUtilities.invokeLater입니다. 실제로 여러 스레드가 사용되는 경우 모든 환경에서 이와 같은 방법이 필요합니다. 그 이유는 기본 UI 스레드가 이벤트 알림 메커니즘을 실행하기 때문입니다. 이 메커니즘과 상호 작용할 수있는 두 번째 스레드는 어떻게 든 동기화되어야합니다.

이러한 호출 메소드는 실제로 개발자가 편리하게 사용할 수 있습니다. 존재하지 않는 플랫폼에서 다른 스레드의 UI 항목에 액세스 할 수있는 것은 아닙니다. 개발자가 맞춤 메커니즘 (이벤트 보내기)을 구현하여이를 수행해야한다는 것을 의미 할 수 있습니다. UI 코드는 스레드 안전성이 거의 없습니다. 필자는 많은 플랫폼과 기술로 작업 해 왔으며 항상이 규칙을 따르고 있습니다. 단일 스레드에서만 UI를 터치하십시오.

0

실제로, 아니오. GUI가 1 개 이상의 스레드를 실행하는 경우에만 필요합니다. WinForm (및 WPF) 응용 프로그램에서는 GUI가 단일 스레드 STA 스레드에서 실행됩니다 (COM으로 거슬러 올라가며 솔직히 모르기 때문에 왜 그런지 묻지 않습니다).

STA 스레드에서 만든 개체를 다른 스레드에서 호출하려고하면 예외가 throw되는지 확인하는 검사가 수행됩니다. WPF는 훨씬 더 우아하게 만듭니다.

어쨌든 Invoke가 필요한 경우 실제로 속성을 확인할 수 있습니다. 이 패턴은 WinForm 응용 프로그램에서 여러 스레드를 처리하는 데 도움이되도록 제안되었습니다.

public void MyTextSetMethod(string text) 
{ 
    if(control.InvokeRequired) 
    { 
     control.Invoke(new Action<string>(MyTextSetMethod), text); 
    } 
    else 
    { 
     control.Text = text; 
    } 
} 

위의 코드는 Text 속성을 설정하기위한 모든 방법을 제공하며 필요에 맞게 맞춤 설정할 수 있습니다.

+0

이것은 STAthread와는 관련이 없거나 없습니다. 사실, STAthread는 COM과 관련이 있지만 interop 용도로만 사용됩니다. Windows에서는 STA 또는 MTA를 만든 스레드가 동일한 스레드에서 컨트롤의 업데이트가 필요합니다. –

1

당신은 틀렸어요. Control.Invoke는 컨트롤에 대한 작업을 수행하는 데 필요하지 않습니다.

Control.Invoke는 스레드 경계에서 코드를 마샬링하는 데 유용한 도구이지만이를 수행하는 유일한 방법은 아닙니다. 백그라운드 스레드에서 작업 할 때 가장 자주 사용되는 것을 볼 수 있습니다.

Windowed 컨트롤 (즉, Windows 창 핸들이 있고 메시지 펌프를 통해 메시지를 처리하는 컨트롤)을 업데이트해야하는 백그라운드 스레드에서 코드를 호출하면 해당 속성이나 컨트롤의 다른 조작을 변경해야합니다. MessagePump 스레드에 제어를 전달해야하며 Control.Invoke는이를 구현하는 데 유용한 방법입니다.

Windows에서 실행되는 ALL 프로그램에서 백그라운드 스레드의 컨트롤을 업데이트하는 함수를 호출 할 수 없습니다. 일부 언어는 백그라운드에서이 세부 정보를 처리 할 수 ​​있지만 그 중 어떤 것도 알지 못합니다.

1

Invoke는 Win32 API PostMessage의 래퍼입니다. 창을 소유 한 스레드 만 창이 액세스 할 수 있습니다. 이것은 Windows가 단일 스레드 일 때까지 거슬러 올라가는 유산입니다. 즉, PostMessage는 사용중인 프로그램 (VB6, Delphi, .NET 등)에 관계없이 Windows에서 실제 윈도우에 액세스하는 올바른 방법이지만 다른 프로그래밍 언어는 우리에게 더 쉽게 사용할 수있는 래퍼를 제공합니다.