如果您终止启动“异步”任务的线程,您会终止该任务吗?
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
之后运行,线程将已经退出。
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
之后运行,线程将已经退出。