2011-05-03 1 views
0

안녕이 심하게 설명하는 경우 :특정 스레드에서 방법 설정/속성을 실행

하는의 나는 두 개의 클래스가 있다고 가정 해 봅시다 모두 나는 종류의 새로운이 멀티 스레딩 물건의 모든 너무 실례하시기 바랍니다 이니

class abc { 
    public string SomeProperty { 
     get { return something; } 
     set { /* This code has to execute in the main application thread */ } 
    } 

    public void SomeMethod() { 
     /* This code also has to execute in the main application thread */ 
    } 
} 

class def { 
    abc obj; 

    public def() { 
     abc = new obj(); 
    } 

    public void SomeMethod() { 
     abc.SomeProperty = "SomeValue"; 
     abc.SomeMethod(); 
    } 
} 

문제는 SomeProperty 및 SomeMethod가 주 응용 프로그램 스레드에서 실행되는 것입니다. 나는 시도했다 :

abc.GetType().InvokeMember("SomeProperty", System.Reflection.BindingFlags.SetProperty, null, abc, new object[] { "SomeValue" }); 
abc.GetType().InvokeMember("SomeMethod", System.Reflection.BindingFlags.InvokeMethod, null, abc, null); 

그러나, 기본 응용 프로그램 스레드에서 실행하는 데 필요한 코드는 주 응용 프로그램 스레드에서 실행되지 않는, 심지어 (내가 그렇게 어쨌든 생각하지 않는다) 내가 가진 InvokeMember에를 사용하여 코드에서 현재 스레드 이름을 출력하려고 시도했으며 주 응용 프로그램 스레드 이름을 출력하지 않습니다.

내가 할 수있는 방법이 있습니까? 만약 내가 일을 나쁘게 설명했다면 알려주세요 :) 고마워요!

+2

설명하십시오 ** 왜 ** 당신은 실행해야 그 코드는 메인 (또는 다른 무엇이든) 스레드에 있습니다. 'InvokeMember'를 사용하는 당신의 접근법은 단지 틀린 말일뿐입니다. 당신의 의도를 분명히하지 않고는 실제 상황에 맞는 정말 유용한 답을 기대할 수 없습니다. –

+0

그리고 WinForms 또는 WPF를 지정하십시오 –

+0

정보 부족에 대해 사과드립니다. 이것은 WinForms 또는 WPF가 아니라 콘솔 응용 프로그램입니다.메인 스레드에서 실행해야하는 많은 이유가 있습니다. 그 중 하나는 Lidgren 네트워크 라이브러리를 사용하는 응용 프로그램을 구축하고 있기 때문에 라이브러리가 수신하는 스레드에서만 네트워크 메시지를 보낼 수 있기 때문입니다. – Jamie

답변

1

InvokeMember은 리플렉션을 사용하여 멤버를 실행하는 방법 일뿐입니다. 스레딩과는 아무런 관련이 없습니다.

나는 정말로 Control.Invoke 또는 Dispatcher.Invoke (또는 비 차단 BeginInvoke 당량)을 찾고 있다고 생각합니다.

물론 적절한 컨트롤이나 디스패처에 대한 참조가 필요하며 다른 스레드에서 실행할 적절한 대리자를 만들어야합니다. Windows Forms 다중 스레딩 (또는 WPF)에 대한 자습서를 찾으려면 많은 예제를 찾아야합니다. (내 네트워크 연결은 현재 쓰레기입니다. 그렇지 않으면 괜찮은 것을 찾으실 것입니다.)

EDIT : 이제 콘솔 앱이라는 것을 분명히 했으므로 어떤 형태로든 작업해야합니다 메시지 펌프의 스레드가 메시지를 여하튼 듣고 않는 한, 다른 코드를 실행하는 방법은 없습니다. 나는 당신이 말한 라이브러리를 사용하지 않았다. 그러나 특정 스레드에서 코드를 실행하도록 강요한다면, Control.Invoke 등의 일부를 제공해야한다.

+0

비트 혼동. 이 컨트롤은 System.Windows.Forms 개체와 관련이 없기 때문에 Control.Invoke를 사용할 수 있다고는 생각하지 않습니다. BeginInvoke를 사용할 수 있습니까? 원하는 스레드에서 실행합니까? 아니면이 Dispatcher.Invoke 문제를 조사해야합니까? – Jamie

+1

@ Jamie : 컨텍스트에 대한 충분한 정보를 제공하지 않았습니다. 어떤 종류의 응용 프로그램을 쓰고 있습니까? "기본 응용 프로그램 스레드"에 대해 이야기합니다. 그러나 임의의 코드를 실행하도록 요청할 수 있으면 해당 스레드는 메시지 펌프 또는 비슷한 것을 실행해야합니다. –

+0

BeginInvoke를 살펴보면서 필요한 항목이 무엇인지 정확하게 생각합니다. BeginInvoke를 호출 할 수있는 MethodInfo의 대리자를 확보 할 수 있습니까? 나는 매우 많은 양의 메소드를 가지고 있으며, 각각의 메소드를 수행하고 대표자를 만들고 싶지 않습니다. 감사합니다 – Jamie

2

이렇게하는 데는 여러 가지 방법이 있지만 나는이 전화 한 내 초기화 코드에서

protected void setTransactionButton(Boolean enabled) 
    { 
     (new Task(() => 
     { 
      transcriptQuitButton.Enabled = enabled; 
     })).Start(uiScheduler); 
    } 

이 : 다음과 같이 선호 된 접근이다

이 이벤트가 UI 스레드에서 발생하는과에 대한 필요성을 제거하는 것입니다 무엇을
uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 

BeginInvoke.

이 당신이 BeginInvoke을 위해 찾을 수있는 다양한 장소가 있지만 익명 함수를 사용할 수있는 경우, 그 하나 개 기사가 여기에 있습니다 :

http://visualstudiomagazine.com/articles/2009/02/01/use-lambda-expressions-for-abstract-delegates.aspx