【问题标题】:Thread.Abort() is not working when AWAIT is used in a Thread. C#在线程中使用 AWAIT 时,Thread.Abort() 不起作用。 C#
【发布时间】:2019-10-16 09:36:30
【问题描述】:

我有一个按钮,当我单击它时,我正在创建一个线程,10 秒后我将中止它。当我再次单击该按钮时,它会创建新线程,但问题是当我使用 AWAIT 时,该线程不会中止。应用程序正在用新创建的线程显示旧线程的值。但是当我不使用 AWAIT 时,它工作正常。下面只是我的代码示例。

带有 AWAIT 的逻辑(您可以在下图中看到旧线程也在运行)

try
        {
            var _Thread1 = new Thread(async () =>
            {
                int i = new Random().Next(10, 99);
                while (true)
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        listBox1.Items.Add($"{i}");
                    }));
                    await Task.Delay(3000);
                }
            });
            _Thread1.Start();
            Thread.Sleep(10000);
            _Thread1.Abort();
        }
        catch (Exception ex)
        {
        }

输出 48 48 48 48 48 48 83 48 83 48 83 48 83

没有等待的逻辑(下面的逻辑工作文件)。

try
        {
            var _Thread1 = new Thread(async () =>
            {
                int i = new Random().Next(10, 99);
                while (true)
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        listBox1.Items.Add($"{i}");
                    }));
                    Thread.Sleep(3000);
                    //await Task.Delay(3000);
                }
            });
            _Thread1.Start();
            Thread.Sleep(10000);
            _Thread1.Abort();
        }
        catch (Exception ex)
        {
        }

输出。 98 98 98 98 79 79 79 79

我也想在线程使用 AWAIT 时中止它。

我可以使用 CancellationToken/Task,但还有其他方法吗?我想知道为什么使用 AWAIT 时线程没有中止。

提前谢谢你。 :)

【问题讨论】:

  • Thread.Abort() 实际上应该称为Thread.InsertBugHere()
  • 你为什么首先使用线程?
  • @AshishSojitra 删除对Thread每一次 调用,每一次调用BeginInvoke 的尝试。只需使用async void Button1_Click(..){ ...; var result= await client.GetStringAsync(someUrl); textBox1.Text=result;...}
  • @AshishSojitra 至于中止,不要。使用 CancellationTokenSource,将取消令牌传递给每个接受它的异步方法,并在需要取消该方法时发出信号。
  • 在很多情况下 Thread.Abort() 无效。不过不用深挖,这里是一个很简单的案例。线程不再运行。它所做的只是让异步代码开始执行,只需要一毫秒的时间。混合线程和异步不是一个好主意,当代码已经在工作线程上运行时,您根本不需要异步。支持任务。

标签: c# multithreading async-await


【解决方案1】:

我想您观察到的行为的原因是异步操作的延续是在 ThreadPool 线程上安排的。因此,即使您已经中止了代码最初运行的线程,但仍会安排延续,然后在不同的线程上执行。

正如 cmets 中已经提到的,您永远不应该将显式线程使用与 async / await 结合起来。此外,对于您正在编写的所有新代码,async / await 是首选方法。

这里是an answer by Stephen Cleary 的链接,它更清楚地说明了这一点。

【讨论】:

  • @HansPassant,你对这篇文章是正确的,它更多的是关于 I/O 绑定调用。我会找到更合适的材料并更新我的答案。谢谢!
  • @HansPassant 我已经更新了我的答案。如果需要进一步改进,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多