2009-08-23 2 views
1

스레드에서 UI 스레드로 다시 데이터를 마샬링하는 방법에 대해 stackoverflow를 검색하여 3.5에서 다양한 방법을 찾았습니다.Control.Invoke 중 하나 이상의 속성을 설정해야합니다.

나에게 더 우아한 해결책 중 하나는; 나는 아직도 람다를 배우기는하지만이 해결책은 Control.Invoke with input Parameters입니다.

코드를 완전히 이해하지 못했지만 사용 방법을 이해하고 있으며 내 문제를 해결하지 못했습니다.

invoke를 호출하고 문자열을 다른 메서드 (DisplayStatusUpdate (msg))에 전달하고 싶습니다. 모든 포인터는 감사하겠습니다. 당신이 원하는대로

private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e) 
    { 
     DisplayStatusUpdate(e.LoggingEvent.RenderedMessage); 
    } 

    private void DisplayStatusUpdate(string text) 
    { 
     _StatusTextBox.Text = _StatusTextBox.Text + text; 
     _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
     _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
     _StatusTextBox.ScrollToCaret(); 
    } 

답변

5

당신은 예를 들어, 많은 매개 변수를 사용하여이 작업을 수행 할 수 있습니다

private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e) 
{ 
    DisplayStatusUpdate(e.LoggingEvent.RenderedMessage); 
} 

private delegate void DisplayStatusUpdateDelegate(string text); 

private void DisplayStatusUpdate(string text) 
{ 
    if(InvokeRequired) 
     this.Invoke(new DisplayStatusUpdateDelegate(DisplayStatusUpdate), text); 
    else 
    { 
     _StatusTextBox.Text = _StatusTextBox.Text + text; 
     _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
     _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
     _StatusTextBox.ScrollToCaret(); 
    } 
} 

내가 크게 코드를 reduct 수있는 현재 프로젝트에서 사용하고있는 다른 방법이있다. 세부 사항은 here입니다.

는 AOP 공장을 사용하여 양식을 작성하십시오

Form f = AOPFactory.Create<Form1>(); 
Application.Run(f); 

을 그리고 당신은 단지 [RunInUIThread] 속성을 이벤트 핸들러를 장식

이 방법을 구현하는 경우

, 당신은해야합니다. Castle의 메소드 차단 모델을 사용하여 필요할 경우 자동으로 호출합니다.

따라서, 위의 코드가된다 :

private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e) 
{ 
    _StatusTextBox.Text = _StatusTextBox.Text + text; 
    _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
    _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
    _StatusTextBox.ScrollToCaret(); 
} 

성능 현명한 약간 느린, 비슷한 것 같다,하지만 당신은 그것을 확인 할 수 무엇을하고 있는지에 따라, 그것은 확실히 적은 코드를합니다.

+0

니스, 고맙습니다. 브랜든. Signature가 DisplayStatusUpdate에 대한 비트를 변경하려고했지만 그걸 못 견딜 수 없다는 것을 알고있었습니다. –

+0

미안하지만 서명은 동일하지만 당신이 의미하는 바를 알고있었습니다. –

2

당신이 (또는 이상) C# 3.5 당신이 코드를 단순화 할 수있다 캡처 변수를 사용할 수 있습니다 사용하는 경우

private void DisplayStatusUpdate(string text) 
{ 
    this.Invoke(new MethodInvoker(() => 
    { 
     _StatusTextBox.Text = _StatusTextBox.Text + text; 
     _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
     _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
     _StatusTextBox.ScrollToCaret(); 
    })); 
} 

컴파일러는 여기에 배후 할 것입니다 무엇을 개최하는 클래스를 생성하는 것입니다 텍스트를 만들려면 MethodInvoker 대리자를 만들고 해당 대리자와 생성 된 클래스의 인스턴스를 Invoke 메서드에 전달합니다. 위의 디자인에서 이것은 물론 코드가 이미 동일한 스레드에서 실행 중이더라도 대리자를 만들고 Invoke를 호출하는 불필요한 작업을 수행합니다. 그러나 나는 이런 식의 방법이 종종 성능 문제가 될 것이라고 생각해서는 안된다고 믿습니다.

매개 변수가없는 Action 대리자 또는 void을 반환하는 매개 변수가없는 다른 위임을 사용하여 MethodInvoker를 바꿀 수 있습니다.

+0

그것은 대단하다! – Brandon