Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# winform-Compact.NETFramework 3.5中的线程_C#_Multithreading - Fatal编程技术网

C# winform-Compact.NETFramework 3.5中的线程

C# winform-Compact.NETFramework 3.5中的线程,c#,multithreading,C#,Multithreading,我在一个函数中有一个线程,它启动实时监控,它基本上打开串行端口并从串行端口持续读取数据。然而,如果我需要终止这个线程,我应该怎么做呢?因为如果我不终止打开特定串行端口并读取数据的正在运行的线程。当我关闭它并再次调用该函数时。无法打开相同的串行端口。我怀疑串行端口没有正确关闭,仍然在一个单独的线程中运行。所以我想我必须终止该线程,以便下次再次打开相同的串行端口。有人知道如何做到这一点吗 我看到一些论坛说Thread.Abort()使用起来很危险。只有在万不得已的情况下才能使用 谢谢你的帮助 Cha

我在一个函数中有一个线程,它启动实时监控,它基本上打开串行端口并从串行端口持续读取数据。然而,如果我需要终止这个线程,我应该怎么做呢?因为如果我不终止打开特定串行端口并读取数据的正在运行的线程。当我关闭它并再次调用该函数时。无法打开相同的串行端口。我怀疑串行端口没有正确关闭,仍然在一个单独的线程中运行。所以我想我必须终止该线程,以便下次再次打开相同的串行端口。有人知道如何做到这一点吗

我看到一些论坛说Thread.Abort()使用起来很危险。只有在万不得已的情况下才能使用

谢谢你的帮助


Charles

首先,您认为其中包含线程,要关闭所有线程,您应该在启动它们之前将所有线程设置为后台线程,然后当应用程序退出时,它们将自动关闭

然后试着这样做:

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
)在希望退出时唤醒线程。

通常,您会设计在后台线程中运行的方法来侦听取消请求。这可以像布尔值一样简单:

//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()

您将需要以这样一种方式来构造代码,以使线程优雅地终止。如果你发布一些代码(线程正在执行的代码)…那么提供一个有用的答案会更容易。+1-如果允许的话,我会添加更多。这是最简单的方法。它只是一个串口读取线程,所以谁在乎操作系统是否在关机时破坏它!与用户代码不同,操作系统可以轻松处理循环和/或阻塞线程。摆弄布尔“停止”标志或定期检查取消状态是最好的,根本不做。如果线程不绝对需要显式终止,就不要这样做!窗体关闭后,该窗体中的线程是否自动终止?@Charles是的,当您退出应用程序时,它将终止所有线程一次。