2013-08-11 7 views
3

내가 가지고있는 다음과 같은 기능과 나는 System.Threading.Thread 내에서 사용하고 싶습니다 : 나는 시도했다C 번호 - 스레드 내에서 "밖으로"매개 변수와 함수를 사용하여

private void tempFunction(int num, out string fullname, out string info) 
{ 
    // Doing a very long scenario. 
    // When finished, send results out! 
    fullname = result1; 
    info = result2; 
} 

이를 사용하는 (button_Click) 이벤트 핸들러에 코드를 다음

private void submit_Button_Click(object sender, RoutedEventArgs e) 
{ 
    string Fullname = string.Empty, Info = string.Empty; 
    int index = 132; 

    Thread thread = new Thread(() => tempFunction(index, out Fullname, out Info)); 
    thread.Start(); 
    thread.Join(); 

    // I always use "MessageBox" to check if what I want to do was done successfully 
    MessageBox.Show(Fullname + "\n" + Info); 
} 

당신은 내가 스레드가 스레드 프로세스의 결과를 얻을 완료 전까지 기다릴 필요가 있기 때문에 내가 thread.Join();를 사용하는 것을 볼 수 있습니다.

위의 코드는 작동하지 않는 것 같습니다. 단지 멈추고 이유를 모르겠습니다!

나는 분명히 뭔가 잘못하고 있습니다. 내가 원하는 것을 어떻게 할 수 있는지 말해 줄 수 있습니까?

+1

쉬운 문제를 먼저 제거하십시오. 스레드없이 실행 해 보셨습니까? 끝나니? –

+4

또 다른 문제는 다음과 같습니다. 스레드를 시작하고 바로 스레드에 참여하면 방금 함수를 호출했을 수 있습니다. 아무것도 여기에서 비동기 적으로 수행되지 않습니다. –

+0

@ ZanLynx 스레드없이 완벽하게 작동하지만 실제로 스레드와 함께 이러한 종류의 함수를 사용하는 방법을 모릅니다.그 함수에 전혀 문제가 없습니다. 주요한 문제는 스레드입니다. –

답변

12

프로그램이 고정 된 사실은 out 매개 변수와 관련이 없습니다.

"처리를 마칠 때까지 호출 스레드 차단". Thread.Join()을 호출하기 때문에 프로그램이 멈 춥니 다. 호출하는 스레드가 UI 스레드이므로 UI가 멈 춥니 다.

await 키워드 (C# 5)하지만 NET 4.5에 대한 종속성을 주어를 사용하는 것입니다 가장 매력적인있는이 문제를 해결하는 방법의 숫자가 있습니다, 당신은 수동으로 대신 계속를 첨부하도록 선택할 수 있습니다 :

Task.Factory.StartNew(() => tempFunction(index, out Fullname, out Info)) 
      .ContinueWith(r => MessageBox.Show(Fullname + "\n" + Info)); 

는 (당신은 Task 클래스를 사용하기 위해 .NET 4.0을 대상으로해야 할 것입니다.)

그 다음 가장 좋은 해결책은 가능성이있을 것입니다 당신이 프레임 워크의 이전 버전으로 제한하는 경우 BackgroundWorker 구성 요소 gi 사용 Windows Forms 응용 프로그램을 사용하는 경우 으로 표시됩니다.

+1

.net 4.0을 사용하려는 경우 Async/await을 사용할 수 있습니다. [BCL update from nuget] (http://www.nuget.org/packages/Microsoft.Bcl.Async)을 다운로드하십시오. –

+1

OP가 ASP.NET을 사용하고있는 것처럼 보이면 요청이 완료되어 다른 스레드를 잊어 버릴 수있는 반대 문제 (* viz *)가 발생할 수 있습니까? – harpo

+0

Aaarghh! 다시 가입()하십시오. 스레드 간 통신, 대기열, 메시지, 작업 및 기타 모든 가능한 수단은 가능한 가장 최악의 선택 인 '스레드 101'사이트/페이지에서 처음으로 배우는 방법입니다. 드렉! –

0

만약 내가 문제를 정확하게 이해했다면, 그게 멈췄을거야. 나에게 문제는 BackgroundWorker 대신 Thread를 사용하는 것이다. 두 번째 이벤트는 UI 이벤트를 계속 처리 할 수 ​​있습니다.

0

이 기능을 사용할 수 있습니까?

Thread th = new Thread(() => 
{ 
    tempfunction(index, out fullname, out info); 
    MessageBox.Show(fullname + ":" + info); 
}); 
2

이 코드는 join 문으로 인해 코드가 완료 될 때까지 UI를 고정시킵니다. 이 문은 현재 스레드 (이 경우 작업자 스레드 완성을 위해 차단할 UI 스레드)를 알려줍니다. 조인이 완료되면 메시지 상자가 표시됩니다.

이미 제안 된대로 작업 클래스를 사용하거나 새로운 async/await 구문을 사용하십시오. 그러나 프레임 워크의 이전 버전을 사용하는 경우 다음을 사용할 수 있습니다.

delegate void TempFunctionDelegate(int num, out string fullname, out string info); 

    private void tempFunction(int num, out string fullname, out string info) 
    { 
     /*do something for a long time*/ 
     Thread.Sleep(5000); 
     fullname = "result1"; 
     info = "result2"; 
    } 

    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     string Fullname = string.Empty, Info = string.Empty; 
     int index = 132; 

     TempFunctionDelegate tempFunctionDelegate = tempFunction; 
     tempFunctionDelegate.BeginInvoke(index, out Fullname, out Info, CallBackToUI, tempFunctionDelegate); 

    } 

    void CallBackToUI(IAsyncResult ar) 
    { 
     var tempFunctionDelegate = ar.AsyncState as TempFunctionDelegate; 
     string fullName = null; 
     string info = null; 
     tempFunctionDelegate.EndInvoke(out fullName, out info, ar); 

     MessageBox.Show(fullName + "\n" + info); 
    } 
+0

내 프로젝트가 프레임 워크 4.0보다 오래된 버전을 대상으로 할 때 가장 좋은 선택입니다. 감사합니다. –