我需要了解这三种使用TPL分解任务的方式之间的区别:
Task.Run(() => _client.RunClient());
vs。
Task.Run(_client.RunClient);
vs。
Task.Run(async () => await _client.RunClient());
假设我具有以下类结构:
public class Controller {
private _client = new Client();
...
public async Task StartClientA() {
await Task.Run(_client.RunClient);
}
public async Task StartClientB() {
await Task.Run(() => _client.RunClient());
}
public async Task StartClientC() {
await Task.Run(async () => await _client.RunClient());
}
}
然后,在客户端中,这是StartClientA,StartClientB和StartClientC的方法签名:
public async Task StartClientA() {
...
}
public async Task StartClientB() {
...
}
public async Task StartClientC() {
...
}
现在,在每种方法中如何调用RunClient之间有什么区别?
让我感到困惑的是后面的代码发生了什么
await Task.Run(...)
Task.Run是否立即返回,并且函数继续执行?还是仅在方法_client.RunClient完成时才完成Task.Run?什么是_client.RunClient在while(true)循环中并且永不退出?这对每种纺纱方法有何影响?
围绕这些调用任务的不同方式的最佳实践是什么?我要等λ吗?我是否在等待Task.Run?我不等待_client.RunClient吗?
很抱歉,一篇帖子中的所有问题。我正在尝试理解这些不同的行为,因此我可以选择最有意义的行为。我已经阅读了很多有关异步/等待的内容,这是我似乎找不到答案的一个问题。
在此先感谢您的帮助。
答案 0 :(得分:2)
我需要了解这三种任务分解方式之间的区别
Task.Run(() => _client.RunClient());
Task.Run(_client.RunClient);
Task.Run(async () => await _client.RunClient());
这些几乎都是相同的。第一个传递一个lambda,然后将其转换为委托。第二个方法传入一个方法组,该方法组将转换为委托;第三个传递一个lambda,然后将其转换为具有async
状态机的委托。
但是就语义而言,它们实际上都是相同的。第三个开销稍大,但是实际应用中的开销很可能很小。
Task.Run是否立即返回,并且函数继续执行?
Task.Run
立即返回Task
。
或者Task.Run仅在方法_client.RunClient完成时完成吗?
这取决于您完成Task.Run
的意思。它立即返回一个任务,但是当某个方法返回一个任务时,则该任务表示该方法的执行。 Task.Run
返回的任务将在RunClient
完成时完成。
什么是_client.RunClient在while(true)循环中并且永不退出?这对每种纺纱方法有何影响?
然后Task.Run
返回的任务将永远不会完成。
围绕这些调用任务的不同方式的最佳实践是什么?我要等λ吗?我是否在等待Task.Run?我不等待_client.RunClient吗?
await
个任务。除非您不应该这样做(例如,任务无法完成)。Task.Run
。除非您需要这样做(例如,将与CPU绑定的代码移出UI线程,或者强制执行线程池上下文)。async
and await
。除非这是一个简单的方法,例如本例中的lambda。