2010-08-17 15 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 2010-08-17 20:51:18

+0

嗨,@dbasnett。它是.NET 3.5 SP1。我不是Thread.Abort的粉丝,但是如果插件忽略了要停止的礼貌请求(共享布尔),我使用Thread.Abort。 – 2010-08-17 22:25:16

+0

正如我所提到的,微软向我们报告了各种各样的错误。请参阅connect.microsoft.com – dbasnett 2010-08-17 22:33:50

回答

0

它没有解释到底是什么出了问题,而是尖端4 this post从基类库团队使得它听起来像在串行中止线程端口操作不受支持:

我们已经有一些错误报告应用程序突然关闭 - 通常是由执行不受支持的行为(例如中断访问串行端口的线程)导致的。在这种情况下,特定的症状是抛出一个无法捕获的单独线程上的ObjectDisposedException。

+0

听起来似乎合理。最后我记得,'Thread.Abort()'被认为是过时的,你应该使用共享标志。 – 2010-08-17 19:07:57

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()作为最后的努力。如果我非常不幸,而且那时恰好插入串口,它会使应用程序崩溃。 – 2010-08-17 20:29:28

相关问题