【发布时间】:2020-01-22 19:05:53
【问题描述】:
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 运行的操作吗?
【问题讨论】:
-
线程中止后的几乎所有事情都是未定义的行为;不要那样做!
-
任务或线程,如果你想能够“取消”,你应该使用 CancellationToken 来通知线程停止工作,正如@Fabjan 所说的“混合线程与异步代码'气味'并且不推荐”
-
Thread.Abort() 没有什么可靠的。这会在线程上引发异常。很多事情都可能发生……例如,考虑 try-catch-finally 块。
标签: c# multithreading async-await task-parallel-library