2011-05-10 2 views
12

안녕 나는 다음을 참조 코드 :이 코드에서 Action을 사용하는 이유는 무엇입니까?

void UpdateMessage (string message) 
{ 
    Action action =() => txtMessage.Text = message; 
    this.Invoke (action); 
} 

왜 액션을 사용하고 여기에 액션을 호출? 왜 그냥 txtMessage.Text = message을 사용하여 함수 본문의 코드를 대체하지 않습니까?


업데이트

코드의 풀러 버전이 코드가 다른 스레드에서 실행 들여 쓰기 등

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     new Thread(Work).Start(); 
    } 

    void Work() 
    { 
     Thread.Sleep(5000); 
     UpdateMessage("My Garden"); 
    } 

    void UpdateMessage(string message) { 
     Action action =() => textBox1.Text = message; 
     this.Invoke(action); 
    } 
} 
+0

이 윈폼에서인가? –

+1

나는 당신이 비즈니스에 "나쁜 코드"라고 부르는 것을 발견했습니다. 실제로 간접 지정이 필요한 시스템의 어떤 곳에서 복사되었을 수 있습니다. 그러나 당신은 100 % 맞습니다. 그렇지 않습니다. – Axeman

+0

@Axeman 제공된 코드에서 UpdateMessage가 항상 GUI 스레드에서 실행된다는 것을 어떻게 알 수 있습니까? –

답변

20

때문에, 구문 강조하여 아래에 재현, 의견 제시 UI에서 시작하여 Invoke으로 UI 스레드에 마샬링되어야합니다.

documentationControl.Invoke()에 대한 상태 :

는 컨트롤의 내부 창 핸들이 들어있는 스레드에서 지정된 대리자를 실행합니다.

기본 Windows 프레임 워크에서 창 핸들에 대한 작업을 창 핸들을 소유 한 스레드가 수행해야하므로이 작업이 모두 필요합니다.

12

UpdateMessage이

당신이 사용하는 경우 단지 txtMessage.Text = message 당신이 CrossThreadOperationException

+0

예,이 UpdateMessage는 기본 UI 스레드가 아닌 다른 스레드에서 호출됩니다. 하지만 txtMessage.Text = message를 사용하는 이유와 거기에 있어야하는 예외를 보지 못했습니까? 감사! – spspli

4

당신은 컨트롤의 속성에서 작업을해야 얻을 것이다 당신이 GUI 요소와 상호 작용하기 위해 메인 스레드로 호출 할 필요가 다른 스레드에서 호출 된 경우 UI 스레드, 그렇지 않으면 예외가 발생합니다.

Control.Invoke()는 창 메시지 루프로 창 메시지를 보내서 대리자를 실행합니다.

그러나이 필요하지 않을 때 불필요한 스레드 동기화 해를 방지하기 위해 코드를 최적화 할 수 있습니다

void UpdateMessage (string message) 
{ 
    if(InvokeRequired) 
    { 
     Invoke((Action)()=>UpdateMessage(message)); 
     return; 
    } 

    txtMessage.Text = message; 
} 
+0

이것은 전체 코드입니다 : – spspli

+0

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; 공간 TestAction { \t 공용 부분 Form1 클래스 : 폼 \t \t \t { 공개를 Form1() { \t \t \t \t \t 의 InitializeComponent(); \t \t \t 새 스레드 (작업) .Start(); \t \t} \t \t 작업 공간() { \t \t \t \t \t 에 Thread.sleep (5000); \t \t \t UpdateMessage ("My Garden"); \t \t} \t \t 공극 UpdateMessage (메시지 문자열) { \t \t \t \t \t 조 작용 =() => = textBox1.Text 메시지; \t \t \t this.Invoke (action); \t \t \t } – spspli

+1

이 코드에서는 생성자에서 시작된 스레드에서 UpdateMessage 메서드를 호출합니다. 현재 시나리오에서는 Control.Invoke() 호출이 필요합니다. –

관련 문제