如果您终止启动“异步”任务的线程,您会终止该任务吗?

If you kill the thread that started a `async` task, do you kill the task?

async方法的一个缺陷是操作可以在不同的线程上执行。这可以通过以下方式验证:

var z = 0;
while (z < 20)
{
   Console.Write(" - Thread: " + Thread.CurrentThread.ManagedThreadId);
   await Task.Delay(1000);
   z++;
}

这将输出如下内容:
- Thread: 1 - Thread: 1 - Thread: 4 - Thread: 6 - Thread: 7 - Thread: 4

在常规方法中,如果您使用:

var z = 0;
while (z < 20)
{
   Console.Write(" - Thread: " + Thread.CurrentThread.ManagedThreadId);
   Thread.Sleep(1000);
   z++;
}

你的输出将是:
- Thread: 1 - Thread: 1 - Thread: 1 - Thread: 1 - Thread: 1 - Thread: 1

现在,如果您将第一个代码封装在 Thread 上,如下所示:

var thread = new Thread(new ThreadStart(async () =>
{
    var z = 0;
    while (z < 20)
    {
        Console.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(1000);
        z++;
    }
}));
thread.Start();

如果你 thread.Abort 你会可靠地终止 async 操作 运行 吗?

您是否尝试过使用调试器单步执行此代码?我认为您会发现,由于没有任何东西等待 ThreadStart 内部的 async,因此线程一遇到第一个 await 就会立即完成,并且循环将被终止。

为什么?因为 async/await 并非旨在 在多个线程上执行方法 。事实上,它可以这样做是其目的的副产品。

它的设计目的是允许在调用堆栈下方的某个时刻,线程在工作的异步部分继续进行的同时做其他事情(比如监听 UI 输入)。 await 的行为是 return 将控制权交给父调用者。由于没有父调用者,线程在 await.

时终止

您可能对 感兴趣,其中对此进行了更详细的解释。

The idea of a async method is that the operation can be executed on different threads.

异步方法的思想是操作需要异步执行,不一定在单独的线程上执行。一些 I/O 操作不需要线程池线程,而是在 I/O 线程上执行。

以下是我会考虑的一些注意事项:

  • 关键字 await 创建了一个状态机来处理异步操作和它的延续。

  • 混合线程与 async 代码 'smells',不推荐。

  • 从技术上讲,如果异步操作在线程池线程上执行,则中止它启动的线程不会终止该操作,但最有可能的是,这意味着您不关心async操作如何结束,如果是故障状态你将无法处理。

  • Thread.Abort 方法在 .Net Core 中不受支持,如果您 运行 它,您将看到:

    "Unhandled exception. System.PlatformNotSupportedException: Thread abort is not supported on this platform"

The idea of a async method is that the operation can be executed on different threads.

没有。 async 方法的思想是一种可以在另一个操作正在进行时暂停,然后可以稍后恢复的方法。一些 async 方法可以在不同的线程上恢复;其他人不能。

if you thread.Abort will you reliably kill the async operation running?

没有。一旦该方法命中第一个 await,线程就会退出。如果 Thread.Abort 在线程到达 await 之前运行,代码将被中止。如果 Thread.Abort 在线程执行 await 之后运行,线程将已经退出。