代码之家  ›  专栏  ›  技术社区  ›  26071986

SerialPort有问题

  •  7
  • 26071986  · 技术社区  · 16 年前

    我正在使用SerialPort与条形码阅读器进行通信(只读)。

    我安装了驱动程序来操作读卡器,就像它是通过Com端口连接的一样,尽管它是一个usb设备。当插入设备时,列表中会显示一个或多个Com端口。

    问题如下。我初始化SerialPort对象以从条形码读取器读取,但是如果读取器被拔出,我就无法正确地完成或处理SerialPort对象,因为它“连接”到的端口不再存在。

    有没有什么办法能让我妥善处理这种情况?或者至少抓住例外?

    6 回复  |  直到 16 年前
        1
  •  14
  •   Hans Passant    16 年前

    唉,这是USB串行端口仿真器的老问题。串口是可以追溯到石器时代的设备。它们以前是拧在车上的,在程序使用时,如果不引来火花和滚滚浓烟,就无法将它们取下。石器时代还包括缺乏任何类型的即插即用支持,因此程序可以检测到该设备突然变为gonzo。

    根据大众的需求,微软在.NET4.0中做了一些改变。实际上不确定在那个版本中会发生什么。如果你还停留在早期版本上,唯一合理的办法就是在USB插槽旁边贴上一个标牌:“使用时不要取下!”这就不可避免地会有人拔下设备至少两次,看看会发生什么。之后他们就厌倦了,让你安静下来。

    非常不合理的解决方法是一个包含以下内容的app.exe.config文件:

    <?xml version ="1.0"?>
    <configuration>
      <runtime>
        <legacyUnhandledExceptionPolicy enabled="1"/>
      </runtime>
    </configuration>
    

    别用它。

        2
  •  6
  •   Micah    14 年前

    Finalize() 方法,该方法由垃圾收集器调用。

    因此,如果继承.NET SerialPort类并重写打开/关闭,则可以执行以下操作:

    在公开赛期间,打电话就行了 GC.SuppressFinalize(Me.BaseStream)

    GC.ReRegisterForFinalize(Me.BaseStream)

    如果USB被拔出,这将抛出一个异常,抱怨对基流的访问。要么检查 .IsOpen 在调用 GC ,或者把它包起来 Try Catch 如果你不信任 每次都返回False。。。

    这就解决了问题,你的应用程序将处理它被拉出的事实,并且当你关闭时它不会崩溃。

    我目前无法使它,然后重新打开端口,如果它插回,但至少有一些进展以外的标签说,不要碰。。。

        3
  •  2
  •   Panagiotis Kanavos    16 年前

    您可以从SerialPort继承并重写Dispose()方法来处理此类异常。您只需吞并异常(Dispose无论如何都不应该抛出)。

    如果要记录异常或以其他方式处理它,则必须检查 处理

    例如。

        public class MySerialPort:SerialPort
        {
            protected override void Dispose(bool disposing)
            {
                try
                {
                    base.Dispose(disposing);
                }
                catch (Exception exc )
                {                    
                    if (disposing)
                    {
                        //Log the error
                    }
                }
    
            }
        }
    
        4
  •  1
  •   Johan Andersson    8 年前

    我通过创建一个单独的处理串行端口的进程来解决这个问题。当串行端口被拔下时,我重新启动进程。现在我可以在不重新启动主应用程序的情况下重新连接到已拔出的串行端口设备。

    TLDR公司;创建一个单独的进程。

    串口过程码

    static void Main(string[] args)
    {
        using (var output = Console.OpenStandardOutput())
        using (var serialPort = new SerialPort(args[0], int.Parse(args[1])))
        {
            serialPort.Open();
            while (serialPort.IsOpen)
            {
                serialPort.BaseStream.CopyTo(output);
            }
        }
    }
    

    主要应用

    var options = new ProcessStartInfo()
    {
        FileName = "Serial Port Process name here",
        UseShellExecute = false,
        RedirectStandardOutput = true,
    };
    
    using(var process = Process.Start(options))
    {
        using (StreamReader reader = process.StandardOutput)
        {
            while (!process.HasExited)
            {
                string result = reader.ReadLine();
                Console.WriteLine(result);
            }
        }
    }
    
        5
  •  0
  •   26071986    16 年前

    .NET4.0也帮不上忙。我已经安装了VS2010-没什么变化。仍会引发未处理的异常。不幸的是,“在USB插槽旁边贴上一个标牌:“使用时不要取下!”似乎是唯一的决定。。。

        6
  •  0
  •   skinnedKnuckles    12 年前