1

我已经解决这个问题很多天了,但我被困在其中,无法弄清楚。问题是当我关闭端口时,我得到了这个著名的错误

The I/O operation has been aborted because of either a thread exit or an application request

我的代码是这样的

 private void MenuItem_Click_1(object sender, RoutedEventArgs e)
        {


            try
            {
                port.ReadExisting();
                port.DiscardInBuffer();         
                if (port.IsOpen)
                {

                    port.Close();
                }

                Window1 caster = new Window1(this);
                caster.ShowDialog();
            }
            catch (IOException)
            {

            }

port.close()执行时,我得到上述错误。如果我取消订阅数据接收事件,即使这样也会发生此错误并且不会被 catch 语句捕获。
我搜索了它并找到了许多示例,那里提供的所有解决方案都已尝试过,但是每次使用应用程序时都让我很烦。
有人可以帮我解决这个问题吗?

4

1 回答 1

4

是的,这是一个无法捕获的异常。它在 SerialPort 类启动的工作线程中引发,以便它可以触发 DataReceived、ErrorReceived 和 PinChanged 事件。自 .NET 2.0 起,工作线程中未处理的异常会终止程序。这篇博文的技巧 #4 中介绍了如何处理这种行为。我不会在这里重复它,因为这是你不应该做的事情,只有纯粹的绝望是一个足够好的理由来考虑它。

根本原因是调用 Close() 方法时设备驱动程序返回的意外 Windows 错误代码。司机应该只是遵守要求,而不是抱怨它。但是,对于模拟 USB 或蓝牙设备的串行端口的驱动程序来说,这很难实现。它们的质量总体上是相当低的。

当您对设备进行不明智的操作时,您特别有可能引发此类意外错误代码。一般来说,USB 设备的一个非常常见的陷阱,当您的程序行为不端时,它们不会给您任何合理的方法来做一些合理的事情。所以你挠了挠头,耸了耸肩,然后拉了连接器。现在你有两个问题。一些设备驱动程序处理得非常糟糕,他们只是让设备消失。即使 SerialPort 类上打开了一个句柄。这不会有好的结果,说得委婉些,当你调用 Close() 时肯定会爆炸。

像在代码中那样关闭端口也是非常不可取的,MSDN 文章 SerialPort.Close() 对此提出了警告。该工作线程需要一段时间才能退出,在这种情况发生之前您无法再次打开端口。这需要不可预知的秒数才能发生。这里的智慧是只在您启动程序时打开端口,并且只在您退出时(或从不)关闭它。从来没有一个有效的选项,尽管你可能会注意到如果核心原因没有解决,终结器线程会在程序退出时爆炸。

因此,这里的常见建议是寻找驱动程序更新,不要在使用设备时弄乱设备,将设备带到停车场并与您的汽车一起运行几次。还有那个技巧#4。

于 2013-09-27T13:23:22.680 回答