2011-08-24 5 views
-2

새 스레드를 만들 수있는 주 스레드 (MainThread)가 있습니다 (NewThread라고합니다). NewThread에서 MainThread에 대한 메소드를 호출 할 메소드를 호출합니다.C# 스레딩 문제

문제는 MainThread에서 NewThread.Join()을 호출하면 MainThread가 종료 될 때까지 기다리기 때문에 NewThread에서 Invoke 메서드를 수행/종료 (그리고 전체 응용 프로그램을 영구적으로 ...) 할 수 있다는 것입니다.

sth 악순환처럼 ... 어떤 아이디어를 해결하는 방법? MainThread에서 NewThread를 종료/중단하고 NewThread를 더 이상 존재하지 않게 할 수있는 가능성이 필요합니다.

내가 충분히 구체적이기를 바란다.

메인 스레드 :

void method() 
    { 
     if(currentthread!=null) 
     { 
      currentthread.Join(); 
      currentthread=null; 
     } 

     sth... 

     Backgroundworker worker = new Backgroundworker(); 
     worker.DoWork += delegate (...) 
      { 
       currentthread=Thread.CurrentThread; 
       Func(); 
      } 
      .... 
} 

NewThread :

delegate void FuncDel(); 
void Func() 
{ 

    if(MainThread.InvokeRequired) 
{ 
    FuncDel funcD = new FuncDel(); 
    MainThread.InvokeRequired(funcD); 
      return; 
} 
.... 
} 
+1

코드를 확인해야합니다. – Woot4Moo

+1

코드를 게시 하시겠습니까? – ChrisNel52

+0

MainThread에서 메서드를 호출하는 데 사용한 기술은 무엇입니까? 어떤 종류의 통제 였나요? – michalczerwinski

답변

2

음, 분명한 대답은 작업자 스레드가가는 기회가 있다면 메인 스레드) (당신의 작업자 스레드에 가입하지해야한다는 것입니다 주 스레드에서 뭔가를 호출하려고합니다.

주 스레드에서 종료를 기다리는 데 Join() 만 사용하는 경우 먼저 Thread.Abort()와 같은 작업을 수행하거나 더 나은 방법으로 뮤텍스 또는 공유와 같은 스레드 동기화 개체를 사용해야합니다 변수를 지정하여 작업자 스레드에 중단해야 함을 나타냅니다. 작업자 스레드가 중단하도록 신호를 보내면 다음 주 스레드가 Join() 할 수 있도록; 작업자 스레드는 주 스레드에서 메소드를 호출하기 전에 중단되었는지 여부를 항상 확인해야합니다.

다른 이유로 Join()을 사용하는 경우 뮤텍스와 같은 스레드 동기화 객체를 다시 조사해야합니다. 이것들은 스레드가 서로 신호를 보내기를 기다릴 수있게합니다. 작업 스레드는 주 스레드가 Invoke()를 수행하기 전에 주 스레드를 "깨우기"때문에 주 스레드가 작업을 수행하는 CPU 시간을 확보 할 수 있습니다.

+0

+1 : 나는 '뮤텍스 (Mutex)'와 같은 상황에서 'EventWaitHandle'을 선호하는 경향이 있지만. –

0

Thread.Join의 역할은 Join 된 스레드가 종료 될 때까지 호출하는 스레드를 차단합니다. 나는 왜 당신이 단순히 다른 스레드에서 호출하려는 경우 조인을 사용하는지 모르겠다. 이전에 언급했듯이 코드는 상황을 명확히하는 데 도움이됩니다.

스레드 스테이트를 폴링하여 구현하면 메인 스레드를 차단할 수없는 경우 Join을 사용하여 스레드의 상태를 확인할 수 있습니다.

0

취소 패턴이 거의 필요하신 것 같습니다. 이 TPL 옵션을보십시오 :

CancellationTokenSource cts = new CancellationTokenSource(); 
Task.Factory.StartNew(() => 
    { 
     if(cts.Token.IsCancellationRequested) 
      return; 

     // Do Stuff 
    }); 

당신은 기본적으로 당신이 할 작업에 대한 작업을 해고 할 수 있습니다, 당신이 그것을 취소해야 할 경우, 당신은 단순히 당신의 예는 예쁜

cts.Cancel(); 

를 호출 할 수 있습니다 뒤얽힌; 일부 메소드를 호출하기 위해 스레드를 회전시킨 상태는 원래 스레드와 아무 관련이 없습니다.

+0

불행히도 TPL은 .net에서 작동합니다. 4.0 - 이전 버전을 사용하고 있습니다. – santBart