【问题标题】:C# Stop Thread using button after thread finished current function loopC# 在线程完成当前函数循环后使用按钮停止线程
【发布时间】:2021-07-02 11:11:14
【问题描述】:

我有一个 Windows 窗体应用程序,它使用开始按钮执行无限循环。我有一个停止按钮,我试图在循环完成一个循环后用它来停止无限循环。

我已尝试使用不允许循环完成的 thread.Interrupt。

我还使用了 thread.abort,这显然不允许循环完成。

我还尝试通过让停止按钮更新一个全局变量来做到这一点,我的线程内的 while 循环依赖该全局变量,但全局变量不会在线程内更新。

主类代码

startbutton()
{
  handle = getHandle();
  Loopclass.loopclass loop = new Loopclass.loopclass(handle);
  thread = new Thread(()=>loop.run());
  thread.Start();
}

stopbutton()
{
  handle = getHandle();
  Loopclass.loopclass loop = new Loopclass.loopclass(handle);
  loop.setCh();
}

循环类代码

//_ch is a global string variable
Run()
{
  while(_ch != "X")
  {
    //do stuff
    string x = "";
    _ch = getCh(x);
  }
}

setCh()
{
  _ch = "X";
}
  
getCh(string x)
{
  x = "X";
  return x;
}

【问题讨论】:

  • 我会尝试使用 CancellationToken:docs.microsoft.com/en-us/dotnet/standard/threading/…
  • 没有什么比得上全局变量了。您需要创建一个具有正确范围的变量,该变量的所有用户都可以看到。那么你提到的想法应该可行。
  • CancellationToken 是停止线程的精巧工具。但是一个共享的布尔“变量”,通常是一个字段,被访问和更新的线程安全基本上也应该是诀窍,虽然它是手工的方式^^

标签: c# multithreading


【解决方案1】:

使用任务和取消令牌:

private CancellationTokenSource tokenSource;
startbutton()
{
  handle = getHandle();
  Loopclass.loopclass loop = new Loopclass.loopclass(handle);
  tokenSource = new CancellationTokenSource();
  var task = Task.Run(() => loop.Run(tokenSource.Token));
}

stopbutton()
{
   tokenSource.Cancel();
   
  //handle = getHandle();
  //Loopclass.loopclass loop = new Loopclass.loopclass(handle);
  //loop.setCh();
}

Run(CancellationToken token)
{
  while(!token.IsCancellationRequested && _ch != "X")
  {
    //do stuff
    string x = "";
    _ch = getCh(x);
  }
}

setCh()
{
  _ch = "X";
}
  
getCh(string x)
{
  x = "X";
  return x;
}

【讨论】:

  • 是的,但我已经从循环和 Settter 和 getter 中删除了 _ch !="X"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多