2009-04-04 3 views
2

참고 : 일련의 부분 : C#: Accessing form members from another classHow to access form objects from another cs file in C#. C에서 다른 스레드의 Invoke를 사용하여 클래스 멤버에 액세스


헬로

,

아이디어는 패킷이 TCP 클라이언트로 전송/수신 될 때 메모를 이용하여 사용자에게 통지한다.

는 수정의 몇 후, 가장 적합한 솔루션은 코드가 있기 때문에 안전하지 않은 스레드의 예외를 throw 호출, 그것은 그러나
var form = Form.ActiveForm as Form1; 
    if(form != null) 
     form.TextValue = "Test asdasd"; 

를 호출되고있어 방법이 하나

public string TextValue 
    { 
     set 
     { 
      this.Memo.Text += value + "\n"; 
     } 
    } 

될 듯 전화. msdn에 해결책을 찾았지만, 거기서 사용한 방법을 얻을 수없는 것 같습니다.

이것은 제 리메이크로 작동하지 않습니다.

private void SetTextMemo(string txt) 
    { 
     if(this.Memo.InvokeRequired) 
     { 
      this.Invoke(SetTextMemo,txt); //error here 
     } 
     else 
     { 
      this.Memo.Text += txt + "\n"; 
     } 
    } 

오류 :

인자는 '1' 'System.Delegate'

인수에 '있어서 기'로 변환 할 수없는 '2' '문자열'로 변환 할 수있는 객체로 [ ] '

기본적으로 Invoke를 사용하여 다른 스레드에서 메모에 액세스하려고합니다 (또는 메모에 텍스트를 추가하는 경우). 이전에는 사용하지 않았기 때문에 실수를 오해 한 것 같습니다.

+0

이벤트 사용은 어떻게됩니까? – bytebender

답변

11

쉬운 방법은 다음과 같습니다 작업 인라인을 할 수있는 익명의 방법을 사용

this.Invoke((MethodInvoker)delegate { 
    this.Memo.Text += txt + "\n"; 
}); 

. 이 다른 스레드에있을 것으로 예상하므로 Invoke를 호출 할 수도 있습니다. 이는 UI 스레드에서도 안전합니다.

+0

이것은 Gravell이 제 베이컨을 구한 두 번째입니다 (그러나 마지막 시간은 아닙니다). 그 때문에 이번 토요일에 쉬게 할 수 있습니다. 내가 너를 주일에 줄 수있을 것 같아. – Chris

1

내가이 모든 스레드 간 업무를 처리하는 데 사용되는 다음

if (this.Memo.InvokeRequired) { 
    this.Invoke((Action)(() => SetTextMemo(txt))); 
} 
+0

그리고 .NET 3.5 for the Action 델리게이트 타입 ;-p –

+0

@Marc, 나는 그것이 3.5 타입임을 잊지 않고있다. 2.0에서 추가되지 않은 이유는 저를 넘어선 것입니다. – JaredPar

0

을 시도 C# 3.0과 3.5 프레임 워크를 사용하는 경우, 그러나 최근에 나는 당신이 단순히 방법을 장식 AOP로 갔다 UI 스레드에서 실행하십시오. 여기에 (PostSharp에서) 예는 다음과 같습니다

public class FormsThreadAttribute : OnMethodInvocationAspect 
{ 
    public override void OnInvocation(MethodInvocationEventArgs eventArgs) 
    { 
    Form f = (Form)eventArgs.Delegate.Target; 
    if (f.InvokeRequired) 
     f.Invoke(eventArgs.Delegate, eventArgs.GetArgumentArray()); 
    else 
     eventArgs.Proceed(); 
    } 
} 
+0

AOP가 반드시 다른 방법보다 먼저 사용해야하는 곳입니다.그러나 PostSharp 및 AOP에 익숙하지 않은 사용자의 경우 게시물에서 정확하게 작동하는 방식을 이해하는 것이 어려울 수 있으며 실제 사용법의 단순함은 무엇입니까? – Groo

+0

글쎄, 나는 PostSharp와 관련된 교재에 대한 링크를 제공 하겠지만, 실제로 허용되지 않는다. ( –

1

귀하의 구현이 방법은 InvokeRequired 속성의 행동이 그것을 방지 할 것없는 무한 같이 Recurse 때문에 가정합니다. 이 가정은 사실 일 수 있지만,이 가능성을 완전히 피하기 위해 함수를 코딩하는 데는 문제가 없습니다. 다음은 내가 제안한 것입니다.

private void SetMemo(string txt) 
    { 
     Memo.Text = txt; 
    } 

    private delegate void MemoSetter(string txt); 

    public void ThreadSafeSet(string txt) 
    { 
     Invoke(new MemoSetter(SetMemo), txt); 
    }