SerialPort 中的错误关闭线程但不更改它的状态并且不引发异常
Error in SerialPort Closes Thread but don't change it's Status and don't raise an Exception
我正在使用下面的代码在单独的线程中阅读 SerialPort
。
我打开 Serial Port
并尝试 read a line
。由于 Serial Port
中没有任何连接,因此出现错误。我期待一些 TimeoutException
被抛出,但是没有!没有抛出异常,任务停止工作!
据我所知,一个Task can be shutdown by returning from it, or throwing an exception,但这段代码也不行。任务停止工作,任务状态保持为 WaitingForActivation
。
这是怎么回事?我需要在我的应用程序中处理此类错误,但我看不到 SerialPort
.
报告的任何类型的异常或错误
我还尝试进入 Tools/Options/Debugging 并关闭 "Enable Just My code (Managed only)",但这没有做任何事情。
代码是:
(我将它放在单击按钮内,以便更容易复制。)
(为了 运行 你需要一根 FTDI 电缆或类似的东西,并且没有任何东西连接到电缆上)。
private void Button_Click(object sender, RoutedEventArgs e)
{
if (Thread.CurrentThread.Name != "Main")
{
Thread.CurrentThread.Name = "Main";
}
Debug.WriteLine(string.Format("Started from thread '{0}'.", Thread.CurrentThread.Name));
TestTask = Task.Run(() =>
{
Thread.CurrentThread.Name = "TestTask";
int i = 0;
Debug.WriteLine(string.Format("Started from thread '{0}'.", Thread.CurrentThread.Name));
while (true)
{
try
{
SerialPort serialPort = new SerialPort("COM14");
while (!serialPort.IsOpen) serialPort.Open(); // Try to open the SerialPort.
Debug.WriteLine(string.Format("From Thread '{0}', Try to read now:", Thread.CurrentThread.Name));
string s = serialPort.ReadLine(); // here's the error.
i++; // this line is never executed.
Debug.WriteLine(string.Format("From Thread '{0}', Loop Count : {1}", Thread.CurrentThread.Name, i));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
);
while(true)
{
Debug.WriteLine(string.Format("From Thread '{0}', TestTask Status: {1}.", Thread.CurrentThread.Name, TestTask.Status));
Thread.Sleep(500);
}
//try // I tried this before the 'while(true)' above to see if there were any Exceptions being thrown to the "outside" but no, nothing here.
//{
// TestTask.Wait();
//}
//catch(AggregateException ae)
//{
// ae.Flatten();
//}
}
程序的输出是这样的:
您遇到此问题的原因可能因与串行端口交互的模块而异。
但是,您需要检查一些事项才能从代码中获得您期望的结果。
首先,TestTask
总是等待激活,只要while(true)
存在无限循环。
其次,SerialPort.Readline
不抛出TimeOutException
等待接收到一行,unless you set the ReadTimeout
propety to a non-zero value.
try-catch
for exception in Task.Run
必须正常工作。
您可以在这个 极其简单的代码 示例中看到它的工作原理,如下所示:
var TestTask = Task.Run(() =>
{
while (true)
{
try
{
throw new Exception();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
});
最后,您仍然希望通过查看 Debug - Exception...(Ctrl+Alt+E)
检查您的 VS 调试器在遇到任何异常时的行为,其中它的选项列可能会有所不同,具体取决于 Just My Code 是否启用,以防您感到困惑。 (我个人更喜欢启用它)。
如果您想要捕获您的应用程序抛出的所有异常,无论它是否会在未来得到妥善处理,请检查该选项中的 Thrown 列 window.
这将导致 VS 调试器在每次抛出异常时中断。
线程被锁定在 ReadLine()
方法中,因为没有定义 ReadTimeout
。线程确实仍在执行,没有错误或异常干扰它。
我只是没想到该方法会阻塞,因为代码文档没有指定该方法将无限期阻塞,直到收到换行符。但是 online documentation 说得很清楚:
By default, the ReadLine method will block until a line is received. If this behavior is undesirable, set the ReadTimeout property to any non-zero value to force the ReadLine method to throw a TimeoutException if a line is not available on the port.
我正在使用下面的代码在单独的线程中阅读 SerialPort
。
我打开 Serial Port
并尝试 read a line
。由于 Serial Port
中没有任何连接,因此出现错误。我期待一些 TimeoutException
被抛出,但是没有!没有抛出异常,任务停止工作!
据我所知,一个Task can be shutdown by returning from it, or throwing an exception,但这段代码也不行。任务停止工作,任务状态保持为 WaitingForActivation
。
这是怎么回事?我需要在我的应用程序中处理此类错误,但我看不到 SerialPort
.
我还尝试进入 Tools/Options/Debugging 并关闭 "Enable Just My code (Managed only)",但这没有做任何事情。
代码是: (我将它放在单击按钮内,以便更容易复制。) (为了 运行 你需要一根 FTDI 电缆或类似的东西,并且没有任何东西连接到电缆上)。
private void Button_Click(object sender, RoutedEventArgs e)
{
if (Thread.CurrentThread.Name != "Main")
{
Thread.CurrentThread.Name = "Main";
}
Debug.WriteLine(string.Format("Started from thread '{0}'.", Thread.CurrentThread.Name));
TestTask = Task.Run(() =>
{
Thread.CurrentThread.Name = "TestTask";
int i = 0;
Debug.WriteLine(string.Format("Started from thread '{0}'.", Thread.CurrentThread.Name));
while (true)
{
try
{
SerialPort serialPort = new SerialPort("COM14");
while (!serialPort.IsOpen) serialPort.Open(); // Try to open the SerialPort.
Debug.WriteLine(string.Format("From Thread '{0}', Try to read now:", Thread.CurrentThread.Name));
string s = serialPort.ReadLine(); // here's the error.
i++; // this line is never executed.
Debug.WriteLine(string.Format("From Thread '{0}', Loop Count : {1}", Thread.CurrentThread.Name, i));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
);
while(true)
{
Debug.WriteLine(string.Format("From Thread '{0}', TestTask Status: {1}.", Thread.CurrentThread.Name, TestTask.Status));
Thread.Sleep(500);
}
//try // I tried this before the 'while(true)' above to see if there were any Exceptions being thrown to the "outside" but no, nothing here.
//{
// TestTask.Wait();
//}
//catch(AggregateException ae)
//{
// ae.Flatten();
//}
}
程序的输出是这样的:
您遇到此问题的原因可能因与串行端口交互的模块而异。
但是,您需要检查一些事项才能从代码中获得您期望的结果。
首先,TestTask
总是等待激活,只要while(true)
存在无限循环。
其次,SerialPort.Readline
不抛出TimeOutException
等待接收到一行,unless you set the ReadTimeout
propety to a non-zero value.
try-catch
for exception in Task.Run
必须正常工作。
您可以在这个 极其简单的代码 示例中看到它的工作原理,如下所示:
var TestTask = Task.Run(() =>
{
while (true)
{
try
{
throw new Exception();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
});
最后,您仍然希望通过查看 Debug - Exception...(Ctrl+Alt+E)
检查您的 VS 调试器在遇到任何异常时的行为,其中它的选项列可能会有所不同,具体取决于 Just My Code 是否启用,以防您感到困惑。 (我个人更喜欢启用它)。
如果您想要捕获您的应用程序抛出的所有异常,无论它是否会在未来得到妥善处理,请检查该选项中的 Thrown 列 window. 这将导致 VS 调试器在每次抛出异常时中断。
线程被锁定在 ReadLine()
方法中,因为没有定义 ReadTimeout
。线程确实仍在执行,没有错误或异常干扰它。
我只是没想到该方法会阻塞,因为代码文档没有指定该方法将无限期阻塞,直到收到换行符。但是 online documentation 说得很清楚:
By default, the ReadLine method will block until a line is received. If this behavior is undesirable, set the ReadTimeout property to any non-zero value to force the ReadLine method to throw a TimeoutException if a line is not available on the port.