2010-08-17 5 views
2

플러그인 기능을 갖춘 응용 프로그램을 작성했으며 플러그 인이 중지 요청에 신속하게 응답하지 않으면 작업자 스레드에서 Thread.Abort()을 호출합니다 . 이것은 대부분의 경우 작동하는 것으로 보이지만 최근에 시리얼 포트에 쓰는 동안 쓰레드가 중단되면 ObjectDisposedException을 던졌습니다. Windows XP에서 일부 USB 대 직렬 드라이버를 사용하면 파란 화면이 나타납니다.ObjectDisposedException 직렬 포트에 쓰는 스레드를 중단 할 때

나는 제작자/소비자 패턴을 사용하여 작업자 스레드가 직렬 포트에 직접 쓰지 않도록 할 수 있다고 생각하지만, 직렬 포트에 대한 더 자세한 정보가 있는지 알고 싶습니다. 괴물. 여기

문제 재현 간단한 예입니다 :

using System; 
using System.IO.Ports; 
using System.Threading; 

class Program 
{ 
    private static SerialPort port = new SerialPort(); 
    static void Main(string[] args) 
    { 
     port.PortName = "COM1"; 
     port.Open(); 
     for (int i = 0; i < 10; i++) 
     { 
      var workerThread = new Thread(Loop); 
      workerThread.Start(); 

      Thread.Sleep(1000); 

      workerThread.Abort(); 

      Thread.Sleep(1000); 
      Console.Out.WriteLine("Finished {0}.", i); 
     } 
    } 

    static void Loop() 
    { 
     for (int i = 0; i < 1000000; i++) 
     { 
      port.Write(new byte[] {0, 0, 0, 0, 0, (byte)(i % 256)}, 0, 6); 
     } 
    } 
} 
+0

.Net은 어떤 버전입니까? USB를 직렬 어댑터에 사용할 때보고 된 버그가 있습니다. 가장 쉬운 테스트는 프로그램이 직렬 포트를 사용하는 동안 사용자의 것과 같은 프로그램을 가져 와서 어댑터를 가져 오는 것입니다. 이 문제는 4.0에서 수정되었습니다. 나는 Thread.Abort의 팬이 아니다. – dbasnett

+0

안녕하세요, @ dbnet. .NET 3.5 SP1입니다. 나도 Thread.Abort의 팬이 아니지만 플러그가 정중 요청 (공유 부울)을 중지한다면 Thread.Abort를 사용한다. –

+0

내가 언급 한 것처럼 다양한 버그가 Microsoft에보고되었습니다. connect.microsoft.com 참조 – dbasnett

답변

0

그것은 잘못을 정확하게 설명하지 않습니다,하지만 기본 클래스 라이브러리 팀 this post의 끝 4는 시리얼 동안 스레드를 중단 같은 소리한다

갑자기 시스템을 종료 할 때 몇 가지 버그가 발생했습니다. 대부분의 경우 SerialPort에 액세스하는 스레드가 중단되는 등의 지원되지 않는 동작이 발생합니다. 이 경우의 특별한 증상은 잡을 수없는 별도의 스레드에서 Throw되는 ObjectDisposedException입니다.

+0

그럴듯한 소리. 마지막으로,'Thread.Abort()'는 쓸데없는 것으로 간주되었고 공유 플래그를 사용해야합니다. –

0

내 컴퓨터에 직렬 포트가없고 테스트 할 수 없으면 도움이 될지 모르지만 내 의견과 함께 표시됩니다.

using System; 
using System.IO.Ports; 
using System.Threading; 

class Program 
{ 
    private static SerialPort port = new SerialPort(); 
    private static readonly object locker = new object(); 
    private static bool abort; 
    static void Main(string[] args) 
    { 
     port.PortName = "COM1"; 
     port.Open(); 
     for (int i = 0; i < 10; i++) 
     { 
      var workerThread = new Thread(Loop); 
      lock (locker) 
      { 
       abort = false; 
      } 

      workerThread.Start(); 

      Thread.Sleep(1000); 

      lock (locker) 
      { 
       abort = true; 
      } 

      Thread.Sleep(1000); 
      if (workerThread.IsAlive) 
      { 
       // Last-ditch effort. 
       workerThread.Abort(); 
      } 

      Console.Out.WriteLine("Finished {0}.", i); 
     } 
    } 

    static void Loop() 
    { 
     for (int i = 0; i < 1000000; i++) 
     { 
      lock (locker) 
      { 
       if (abort) 
       { 
        return; // or break would work here in this case... 
       } 
      } 

      port.Write(new byte[] {0, 0, 0, 0, 0, (byte)(i % 256)}, 0, 6); 
     } 
    } 
} 
+0

예, 내 응용 프로그램은 공유 플래그를 사용하여 플러그인과 통신합니다. 플러그 인이 규칙을 따르지 않고 중단 플래그가 설정된 후 계속 실행되면 문제가 발생합니다. 그 시점에서, Thread.Abort()를 최후의 노력으로 사용합니다. 매우 운 좋게도 그 순간에 플러그 인이 직렬 포트에 액세스하는 경우 응용 프로그램이 충돌합니다. –

관련 문제