【问题标题】:Threading in winform - Compact .NET Framework 3.5winform 中的线程 - Compact .NET Framework 3.5
【发布时间】:2012-04-05 06:37:18
【问题描述】:

我在一个函数中有一个线程来启动实时监控,它基本上是打开串口并不断从串口读取数据。但是,如果我需要终止这个线程,我应该怎么做呢?因为如果我不终止打开特定串口并读取数据的正在运行的线程。当我关闭它并再次调用该函数时。同一个串口打不开。我怀疑串口没有正确关闭,并且仍在单独的线程中运行。所以我认为我必须终止该线程以便下次再次打开相同的串行端口。有谁知道如何实现这一目标?

我看到一些论坛说 Thread.Abort() 使用起来很危险。它应该只在最后的手段下使用。

感谢您的帮助。

查尔斯

【问题讨论】:

  • 您将需要以使线程优雅地终止的方式来构造您的代码。如果您发布一些代码(线程正在执行的代码)...提供有用的答案会更容易。

标签: c# multithreading


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    首先认为你有线程,要关闭所有线程,你应该在启动它们之前将它们全部设置为后台线程,然后它们将在应用程序退出时自动关闭。

    然后试试这个方法:

    Thread somethread = new Thread(...);
    someThread.IsBackground = true;
    someThread.Start(...); 
    

    参考http://msdn.microsoft.com/en-us/library/aa457093.aspx

    【讨论】:

    • +1 - 如果允许,我会添加更多。这是最简单的方法。它只是一个串行端口读取线程,所以谁在乎操作系统是否在关机时破坏它!与用户代码不同,操作系统可以轻松应对循环和/或阻塞线程。摆弄布尔“停止”标志或定期检查取消状态最好根本不做。如果线程不需要显式终止,请不要这样做!
    • 表单关闭后,该表单中的线程是否会自动终止?
    • @Charles-是的,当您退出应用程序时,它将终止所有线程。
    【解决方案3】:

    使用最初设置为 false 的布尔标志,当您希望线程退出时,将其设置为 true。显然,您的主线程循环需要监视该标志。当它看到它变为 true 时,您的轮询,关闭端口并退出主线程循环。

    您的主循环可能如下所示:

    OpenPort();
    while (!_Quit)
    {
        ... check if some data arrived
        if (!_Quit)
        {
            ... process data
        }
    }
    ClosePort();
    

    根据您等待新数据的方式,您可能希望利用事件(ManualResetEventAutoResetEvent)在您希望线程退出时唤醒线程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多