Dan*_*ite 7 c# multithreading serial-port exception stream
大家下午好!
我有这个线程SerialPort包装器从串行端口读取一行.这是我的线程代码.
protected void ReadData()
{
SerialPort serialPort = null;
try
{
serialPort = SetupSerialPort(_serialPortSettings);
serialPort.Open();
string data;
while (serialPort.IsOpen)
{
try
{
data = serialPort.ReadLine();
if (data.Length > 0)
ReceivedData(serialPort, new ReceivedDataEventArgs(data));
}
catch (TimeoutException)
{
// No action
}
}
}
catch (ThreadAbortException)
{
if (serialPort != null)
serialPort.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
当我打电话给myThread.Abort();我得到一个例外(没有行或代码参考)"安全句柄已关闭".谁能发现我做错了什么?谢谢.
顺便说一句,我有一个Start()和一个Stop()创建线程并恭敬地中止线程.
Mik*_*scu 10
我怀疑这是因为你使用Thread.Abort来结束线程 - 这通常是不赞成的.中止它时的线程行为是不可预测的.因此,由于串行端口是本机代码的包装器,因此存在本机资源(由.NET中的SafeHandle表示),这些资源会被意外处理掉,因此您将获得异常.
您可以考虑这样的线程会发生什么:
你真的应该使用一种不同的方法来中止线程,这样你就有机会关闭和处理串口.
可以使用如下的ManualResetEvent实现关闭线程的正确方法:
protected ManualResetEvent threadStop = new ManualResetEvent(false);
protected void ReadData()
{
SerialPort serialPort = null;
try
{
serialPort = SetupSerialPort(_serialPortSettings);
serialPort.Open();
string data;
while (serialPort.IsOpen)
{
try
{
data = serialPort.ReadLine();
if (data.Length > 0)
ReceivedData(serialPort, new ReceivedDataEventArgs(data));
}
catch (TimeoutException)
{
// No action
}
// WaitOne(0) tests whether the event was set and returns TRUE
// if it was set and FALSE otherwise.
// The 0 tells the manual reset event to only check if it was set
// and return immediately, otherwise if the number is greater than
// 0 it will wait for that many milliseconds for the event to be set
// and only then return - effectively blocking your thread for that
// period of time
if (threadStop.WaitOne(0))
break;
}
}
catch (Exception exc)
{
// you can do something here in case of an exception
// but a ThreadAbortedException should't be thrown any more if you
// stop using Thread.Abort and rely on the ManualResetEvent instead
}
finally
{
if (serialPort != null)
serialPort.Close();
}
}
protected void Stop()
{
// Set the manual reset event to a "signaled" state --> will cause the
// WaitOne function to return TRUE
threadStop.Set();
}
Run Code Online (Sandbox Code Playgroud)
当然,当使用events方法来停止线程时,您必须小心地在所有长时间运行的循环或任务中包含事件状态检查.如果你不这样做,你的线程似乎不会响应你的设置事件 - 直到它退出长时间运行的循环,或任务并有机会"看到"事件已被设置.
| 归档时间: |
|
| 查看次数: |
16765 次 |
| 最近记录: |