2012-04-05 2 views
2

PC의 USB 포트에 연결된 USB-CAN 변환기와 상호 작용하는 C# (Visual Studio 2010)으로 개발 된 Windows 응용 프로그램이 있습니다. 하나의 스레드에서 UI를 구현하고 별도의 스레드에서 전송 및 수신 논리를 구현했습니다. 내 작업이 끝나면이 스레드를 닫고 현재 걸려있는 UI 스레드로 돌아가고 싶습니다 !!C# 멀티 쓰레딩 문제

강제 종료 기능을 사용하여 스레드를 강제 종료하려고 시도했지만 예외가 발생합니다. 어떻게 성공적으로이 작업을 끝내야합니까?

나는 다음 두 질문이 있습니다

  1. 어떻게 정상적으로 스레드를 종료하고 UI 스레드에 반환을?
  2. 왜이 전송 및 수신 스레드가 UI 스레드를 중단하고 정지시키지 않습니까?

코드의 아래 부분은 참조 용입니다 :

#region recievedthrad 
public void ThreadProcReceive() 
{ 
    try 
    { 
     bool fDoExit = false; 

     do 
     { 
      if (bFlag) 
       DeleteAllResources(); // This will free all the driver resources. 

      // wait for receiving messages or exiting this thread 
      /* Note: After completion of the task, this method needs to return a 0 or 2 value. But still it returns 1 or 258 and never exits the thread. */ 

      int index = WaitHandle.WaitAny(m_RxWaitHandles); 
      if (index == 0) 
      { 
       // exit this thread 
       fDoExit = true; 
      } 
      else if (index == 1) 
      { 
       // receive all messages 
       ReceiveAllCanMessages(); 
      } 
      else if (index == 2) 
      { 
       // exit this thread 
       ReceiveStatus(UcanDotNET.USBcanServer.USBCAN_CHANNEL_CH0); 
      }  
     } while ((fDoExit == false)); 
    } 
    catch(Exception ex) 
    { 

    } 
} 
#endregion 
+2

혼란 스럽습니다. GUI 스레드와 USB/CAN 통신을하는 다른 스레드가 있습니다. 왜 GUI 쓰레드가 걸려 있습니까? comms 스레드가 종료하고 핸들 (Thread.Join)에서 대기하도록 신호를 보내려고하기 때문에 매달려 있다면 그냥하지 마십시오! 끝내기 위해 신호를 보내십시오. 음, 그냥 기다리지 마십시오. 당신은 어쨌든 끝내야합니까 - 그냥 주변에 놓아 두지 않는 이유는 무엇입니까? –

+3

이것은 BackgroundWorker를 사용하기에 좋은 곳이 될 수 있습니다 –

+2

'index == 2 '의 경우'/ /이 스레드를 종료하십시오'라는 주석이 있지만'fDoExit = true'를 설정하지 않았습니다. – Henrik

답변

0

어떻게 정상적으로 스레드를 종료하고 UI 스레드로 돌아가려면?

스레드가이 라이브러리가 정상적으로의 작업 중 하나를 종료 할 수있는 능력을 가지고 있다고 가정 ... 다음 차단을 해제하기 위해 다른 UcanDotNet API를 사용해야합니다 호출 UcanDotNet 이들 중 하나 내부에 차단됩니다. 이 UcanDotNet 라이브러리에 익숙하지 않아 그 기능이 무엇인지 알 수 없습니다.

대부분의 세 번째 라이브러리와 마찬가지로이 UcanDotNet 라이브러리가 작업을 취소하는 데 필요한 수단을 제공하지 않으면 실제로 다른 선택의 여지가 없지만이 모든 호출을 다른 프로세스에 넣고 WCF를 통해 통신 할 수 있습니다. 그렇게하면 갑자기 종료해야한다면 프로세스를 죽일 수 있습니다. 스레드를 중단하면 메모리가 손상 될 수 있기 때문에 다른 프로세스를 종료하면 Thread.Abort을 호출하는 것보다 안전합니다.

왜이 송수신 스레드가 중단되고 정지하지 않는가? UI 스레드?

Thread.Abort은 차단 호출입니다. 스레드에 중단이 주입 될 때까지 대기합니다. 귀하의 문제는 스레드가 finally 블록 또는 관리되지 않는 코드와 같은 비동기 예외 주입을 허용하지 않는 컨텍스트에서 실행되고 있다는 것입니다. 다음 코드를 사용하여 쉽게 설명 할 수 있습니다.

public static void Main(string[] args) 
{ 
    int i = 0; 
    var t = new Thread(() => 
    { 
     try 
     { 
     } 
     finally 
     { 
      while (true) i++; 
     } 
    }); 
    t.Start(); 
    Thread.Sleep(1000); 
    t.Abort(); // this blocks indefinitely! 
    Console.WriteLine("aborted"); // never gets here! 
} 
관련 문제