我在启动实时监控的函数中有一个线程,它基本上打开串口并不断从串口读取数据。但是,如果我需要终止这个线程,我应该怎么做呢?因为如果我不终止打开特定串口并读取数据的正在运行的线程。当我关闭它并再次调用该函数时。同一个串口打不开。我怀疑串口没有正确关闭,并且仍在单独的线程中运行。所以我认为我必须终止该线程以便下次再次打开相同的串行端口。有谁知道如何实现这一目标?
我看过一些论坛说 Thread.Abort() 使用起来很危险。它应该只在最后的手段下使用。
感谢您的帮助。
查尔斯
我在启动实时监控的函数中有一个线程,它基本上打开串口并不断从串口读取数据。但是,如果我需要终止这个线程,我应该怎么做呢?因为如果我不终止打开特定串口并读取数据的正在运行的线程。当我关闭它并再次调用该函数时。同一个串口打不开。我怀疑串口没有正确关闭,并且仍在单独的线程中运行。所以我认为我必须终止该线程以便下次再次打开相同的串行端口。有谁知道如何实现这一目标?
我看过一些论坛说 Thread.Abort() 使用起来很危险。它应该只在最后的手段下使用。
感谢您的帮助。
查尔斯
通常,您设计在后台线程中运行的方法来侦听取消请求。这可以像布尔值一样简单:
//this simply provides a synchronized reference wrapper for the Boolean,
//and prevents trying to "un-cancel"
public class ThreadStatus
{
private bool cancelled;
private object syncObj = new Object();
public void Cancel() {lock(syncObj){cancelled = true;}}
public bool IsCancelPending{get{lock(syncObj){return cancelled;}}}
}
public void RunListener(object status)
{
var threadStatus = (ThreadStatus)status;
var listener = new SerialPort("COM1");
listener.Open();
//this will loop until we cancel it, the port closes,
//or DoSomethingWithData indicates we should get out
while(!status.IsCancelPending
&& listener.IsOpen
&& DoSomethingWithData(listener.ReadExisting())
Thread.Yield(); //avoid burning the CPU when there isn't anything for this thread
listener.Dispose();
}
...
Thread backgroundThread = new Thread(RunListener);
ThreadStatus status = new ThreadStatus();
backgroundThread.Start(status);
...
//when you need to get out...
//signal the thread to stop looping
status.Cancel();
//and block this thread until the background thread ends normally.
backgroundThread.Join()
首先认为您有线程并关闭所有线程,您应该在启动它们之前将它们全部设置为后台线程,然后当应用程序退出时它们将自动关闭。
然后尝试这种方式:
Thread somethread = new Thread(...);
someThread.IsBackground = true;
someThread.Start(...);
使用最初设置为 false 的布尔标志,当您希望线程退出时,将其设置为 true。显然,您的主线程循环需要监视该标志。当它看到它更改为 true 时,您的轮询,关闭端口并退出主线程循环。
您的主循环可能如下所示:
OpenPort();
while (!_Quit)
{
... check if some data arrived
if (!_Quit)
{
... process data
}
}
ClosePort();
根据您等待新数据的方式,您可能希望使用事件(ManualResetEvent
或AutoResetEvent
)以便在您希望线程退出时唤醒您的线程。