2011-04-11 2 views
0

다음과 같은 상황은 다음과 같습니다C#에서 스레드를 통해 다른 클래스의 이벤트를 호출

내가 메인 폼을 생성하는 클래스가 있습니다. 난 단지를 계속해야 지금

mainAppWnd = new MainAppWnd(); 

: 그것은이 같은 정적 멤버로 기본 폼의 생성 된 객체를 유지 :

public static mainAppWnd; 

과 양식이 같은 main 코드 어딘가에 작성 이 애플리케이션의 한 인스턴스가 한 번에 열리고 뮤텍스를 통해이 작업을 수행하고 있습니다. 그 부분은 잘 작동합니다. 그 응용 프로그램의 두 번째 인스턴스가 열리면, 나는 그것이 명령 행 인자를 포함하고 있는지 아닌지를 확인해야한다. 그렇다면 실행중인 기존 인스턴스에 명령 줄 args를 전달하고 실행중인 인스턴스 내부에 새 폼을 열어야합니다. 이 새 양식의 개설은 MainAppWnd 클래스에서 처리됩니다. 이 작업을 수행하기 위해 파이프를 사용하고 스레드에서 Listen을 사용했습니다. 내 스레드 함수는 다음과 같습니다.

public static void Listen() 
{ 
    NamedPipeServerStream server = new NamedPipeServerStream("49A252BB-C0FC-4bdb-8CA7-522A3BAE3432"); 
    server.WaitForConnection(); 

    byte[] buffer = new byte[1000]; 
    int bytesread = server.Read(buffer, 0, 1000); 

    string args = Encoding.UTF8.GetString(buffer, 0, bytesread - 1); 
    args.Trim(); 
    string[] arrArgs = args.Split(' '); 
    mainAppWnd.LaunchNewForm(arrArgs.ToList()); //This line crashes because of a UI Call across threads. 
} 

위의 코드에서 스레드 간 UI 호출로 인해 마지막 줄이 충돌합니다. 이제는 어떻게 든 MainAppWnd에 비동기 적으로 메시지를 전달해야하므로이 새로운 양식이 기존의 컨텍스트에서 시작되지만 아직 수행 할 수 없었습니다. C++이라면 간단히 ::PostMessage()을 작성했을 것입니다.하지만 C#에서 이렇게하는 가장 간단한 방법은 무엇입니까?

답변

2

은 Windows 양식입니다 가정 및 mainAppWnd가있는 Form 또는 이와 유사한, 당신은 사용할 수 있습니다

Action action =() => mainAppWnd.LaunchNewForm(arrArgs.ToList()); 
mainAppWnd.BeginInvoke(action); 

Control.BeginInvokeControl.Invoke하면 컨트롤과 관련된 UI 스레드에서 대리자를 실행하는 데 사용되는 당신을 그들에게 전화 해. 두 가지의 차이점은 BeginInvoke이 비동기 (화재 및 잊어) 인 반면 Invoke은 대리인이 실행될 때까지 차단된다는 것입니다.

+0

고마워요. Invoke 및 BeginInvoke는 분명합니다. '() => mainAppWnd.LaunchNewForm (arrArgs.ToList()); 뒤에있는 마법에 대해 설명해 주시겠습니까? 조금? – Aamir

+0

@Aamir : 그것은 단지 람다 표현식입니다 - 완전히 다른 방법을 쓰지 않고 델리게이트를 생성하는 쉬운 방법입니다. –

+0

감사합니다. 나는 너의 책으로 돌아왔다. :) – Aamir

관련 문제