【问题标题】:How to ignore an exception AND complete the try如何忽略异常并完成尝试
【发布时间】:2013-02-22 08:01:48
【问题描述】:

所以我已经和this issue 斗争了大约一个星期,我认为我知道这个问题,但我不想在那里报告答案,直到我确定它为止。

简而言之,我在尝试使用 SerialPort.Open() 命令时收到 IOException。事实证明,这是很常见的,大多数终端程序实际上也是如此,但他们只是忽略了它。请阅读我上面的帖子以获取完整的故事。现在我想做的是忽略 IOException 但仍然打开串口。我不能用 try/catch 做到这一点,或者至少我不知道怎么做。

我想知道有没有办法尝试一些事情并以某种方式声明“我知道会抛出一个问题,这是一个安全的问题,我选择忽略异常并继续执行任务”。需要明确的是,我不想忽略错误然后继续。我想忽略错误并仍然完成操作

以下是我的最佳猜测,但它不起作用。

        try
        {
            serialPort1.Open();               
        }
        catch (System.IO.IOException)
        {
            MessageBox.Show("An IO Exception occurred.");
        }
        finally
        {          
            //SAFELY IGNORE ERROR AND DO TASK ANYWAY HERE
        }

如果有人能帮我解决这个问题,我将不胜感激。

编辑:如果我之后添加代码serialport1.Open,我会得到:

这与没有 try/catch 的情况基本相同。我想做的是说我正在尝试这样做:我不在乎它会引发错误,无论如何都要这样做。

【问题讨论】:

  • 如果您再试一次,serialPort1.Open() 似乎不会成功。什么都没有改变,为什么你会期待不同的结果?
  • 您确定问题出在 finally 块而不是该 finally 块中的代码吗?
  • 你是说当你调用 Open() 时,串口实际上并没有因为错误打开?
  • 是的,这正是我要说的。
  • 您可以忽略异常,但是您仍然不会打开串行端口。在某些情况下,您必须有嵌套的 try/catch,但看起来情况并非如此。我建议您尝试找到一种访问串行端口的替代方法,您很可能需要做一些较低级别的事情。

标签: c# serial-port ioexception


【解决方案1】:

一般来说,如果您有一行代码导致异常,并且无论是否发生异常都需要完成额外的工作,您应该使用catch,并将您想要完成的东西放在外面(之后)try/catch


对于您的特定情况(在您的其他问题中描述),您正在处理 .NET System.IO.Ports.SerialPort 的可怕破坏。打开串行端口成功,但SerialPort.Open 是一种复杂的方法,它会做很多额外的事情,并且如果任何额外(和不必要的)事情失败,就会坚持关闭端口。我还发现了 System.IO.Ports.SerialPort 的其他问题(例如,无法通过其内部设备名称打开端口)。 IMO,你越早摆脱 System.IO.Ports.SerialPort 越好。

您可以 p/调用 Win32 串行端口函数(CreateFile,其余为 here)或找到已经编写了包装库的人(我做过,但它不公开)。

【讨论】:

  • 抱歉,这不是我真正想要的。如有误解,请再次阅读完整问题。
  • @tmwoods:现在我看到您说“忽略 IOException 但仍然打开串口”(在我专注于“仍然完成操作”之前,我预计这意味着您的任何部分代码没有使用串口)。你不能。打开串口失败后,您的代码可以继续,但端口未打开,因此您将无法执行任何需要打开串口的操作。要使用串口,​​首先需要成功地打开它
  • 嗯。我默认使用其他人的专业知识,因为我还是 C# 的新手,但我仍然觉得必须有一种方法来完成这项工作。例如,当您添加 myPort.DataReceived += new SerialDataReceivedEventHandler(myPort_DataReceived);它安全地忽略了由多线程引起的错误。有没有办法解决其他错误?或者这仅仅是创建处理程序的正确方法?
  • @tmwoods:您遇到了一个可以简单地忽略并继续的错误(对 UI 的跨线程访问)这一事实并不意味着所有错误都毫无意义。如果打开串口失败,则无法继续使用串口,​​就好像没有失败一样。你只能做与串口无关的事情。或者你可以再试一次,就像大卫建议的那样。
  • 我想我认为可以做到的原因是因为我使用和使用 COM 端口监视器分析的每个终端程序都会引发相同的错误,但不知何故忽略了它,我愿意打赌其中至少有一个(到目前为止我已经测试了 4 个)是用 C 开发的。我仍在寻找一个像样的开源程序,它可以成功连接以查看代码。我只是觉得在这一点上承认失败是我认为必须作为编译器和 IDE 的一部分存在的东西的巨大代价。
【解决方案2】:

serialPort1.Open();

是什么引发了异常。通常,当您编码时,如果发生异常,您会清理连接。

正如其他人所提到的,如果您继续调用相同的方法,除非调用发生变化,否则您将不断收到异常。

所以理解,我的建议是你寻找其他方法来打开串口,除了 serialPort1.Open();称呼。在 C# 中可能有也可能没有构建方式。所以你可能必须要有创意:)

【讨论】:

  • 我觉得必须有一种方法可以安全地忽略已知错误。这是一个我正在慢慢学习的 .NET 错误,众所周知但未修复。肯定有办法忽略这些事情。
  • 如果他愿意放弃 .NET SerialPort 类,Win32 API 的串口功能会好很多。并获得更多有用的错误信息。
  • @Ben Voigt,我同意,我认为你的建议很好:)
  • @tmwoods,有时错误的东西会被释放,然后会贬值,然后被更好的东西取代。我建议遵循 Ben 的建议。
  • @VenomFangs:是的,但是.... Win32 函数早在 .NET 之前就已经存在了。事实上,.NET SerialPort 使用它们(不正确)。
【解决方案3】:

来自SerialPort.Open

每个 SerialPort 对象只能存在一个打开的连接。 任何应用程序的最佳做法是在调用 Close 方法后等待一段时间,然后再尝试调用 Open 方法,因为端口可能不会立即关闭。

端口处于无效状态。

  • 或 -

设置底层端口状态的尝试失败。例如,从此 SerialPort 对象传递的参数无效。

我敢打赌这就是正在发生的事情...您的 SerialPort 最近打开了,现在您正试图在它准备好之前再次打开它。

我的建议是编写一个循环,并在两次打开尝试之间睡一会儿。弄清楚你愿意在多长时间内尝试多少次。 break 成功后退出循环。

foreach(int i in Enumerable.Range(1, numberOfAttempts)
{
  try
  {
    serialPort1.Open();
    break;
  }
  catch(Exception ex)
  {
    //log attempt #i failed because of ex
  }
  Thread.Sleep(millisecondsToWait);
}

【讨论】:

  • 不,这不是正在发生的事情。请阅读上面链接的完整主题。
猜你喜欢
  • 2023-03-30
  • 2019-07-11
  • 2015-04-14
  • 2020-09-20
  • 1970-01-01
  • 2014-02-12
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多