我正在存储我的数据模型的状态。我克隆数据模型,然后想要将其写入“磁盘”异步。什么时候应该使用Task.Run()而不是等待?
我应该使用Task.Run()在后台线程上运行它吗? 或者我应该让它成为一个异步函数,而不是等待它? (这将使其在UI线程上运行)
类似的东西,这一点,但我的问题是有点不同: async Task.Run with MVVM
什么是决定其选择标准是什么?
谢谢!
我正在存储我的数据模型的状态。我克隆数据模型,然后想要将其写入“磁盘”异步。什么时候应该使用Task.Run()而不是等待?
我应该使用Task.Run()在后台线程上运行它吗? 或者我应该让它成为一个异步函数,而不是等待它? (这将使其在UI线程上运行)
类似的东西,这一点,但我的问题是有点不同: async Task.Run with MVVM
什么是决定其选择标准是什么?
谢谢!
对于要在线程池线程上运行的基于CPU的工作,应该使用Task.Run
。
在您的情况下,您希望在不阻止用户界面的情况下执行基于I/O的工作,因此Task.Run
不会为您提供任何帮助(除非您没有可用的异步I/O API)。
作为一个附注,你绝对要做想要await
这项工作。这使得错误处理更清晰。
所以,这样的事情应该足够了:
async void buttonSaveClick(..)
{
buttonSave.Enabled = false;
try
{
await myModel.Clone().SaveAsync();
}
catch (Exception ex)
{
// Display error.
}
buttonSave.Enabled = true;
}
我不认为这很重要。据我所知,这两种方法都被分派到线程池中的一个线程。
使用async
将让后台线程异步方法运行,并继续启动它当异步方法完成的线程上。您可以想象编译器会看到await关键字,将等待的方法放在后台线程中,并配置事件以注意异步方法完成时的注意事项。因此,如果由于成功保存而想要显示UI更改,并且因为这当然是较少的代码,所以这可能是更好的选择。
Task.Run()
当你出于任何原因不希望将代码放在async
方法中时会更好,例如因为您希望调用方法本身不是异步。此外,还有较少的事件编组参与,但我非常怀疑有任何性能差异。
嗯...你确定吗?我认为异步的整个架构是在同一个线程上继续执行*。否则,它不会“让开发人员更容易”。 – swinefeaster
来自[TAP](http://www.microsoft.com/en-us/download/details.aspx?id=19957):“如果SynchronizationContext与挂起时执行异步方法的线程相关联(例如SynchronizationContext.Current是非空的),异步方法的恢复将通过使用上下文的Post方法在同一个SynchronizationContext上发生,否则,它将依赖于任何System.Threading.Tasks.TaskScheduler当时的当前状态的暂停(通常这将是TaskScheduler.Default,其目标是.NET ThreadPool)“ – Christian
这就是我所说的。异步方法的执行是从线程池执行到另一个线程,并在完成时返回调用线程,其余方法结束。 – Akku
谢谢。这是暂停,所以我绝对不想向用户显示任何错误。无论如何,他们无法用它做很多事情,如果它没有保存,应用程序就会恢复(如果有的话,更多的是缓存)。 – swinefeaster