2012-04-08 99 views
6

我试图在不冻结UI的情况下在后台执行操作。在不冻结UI的情况下运行长时间任务

当然,我可以为此使用BackgroundWorker。

但是,我只想用Task API来完成它。

我想:

async void OnTestLoaded(object sender, RoutedEventArgs e) 
{ 
    await LongOperation(); 
} 
// It freezes the UI 

async void OnTestLoaded(object sender, RoutedEventArgs e) 
{ 
    var task = Task.Run(()=> LongOperation()); 
    task.Wait(); 
} 


// It freezes the UI 

所以,我应该回去的BackgroundWorker?或者只有使用任务的解决方案?

+0

为什么很多人不喜欢BackgroundWorker?我喜欢它,并直接找到语法。 – Paparazzi 2012-04-08 20:15:04

+0

'BackgroundWorker'远远好于'Thread',但'基于Task'的API最终将占据主导地位。我有[相关的博客文章](http://nitoprograms.blogspot.com/2010/08/various-implementations-of-asynchronous.html)。 'Task.Run'具有以下优点:(1)允许嵌套; (2)取消支持使用统一的'CancellationToken'系统; (3)异常使用正确的调用堆栈更自然地传播; (4)更自然地检索结果; (5)使用较少的资源(线程池而不是专用线程)。 – 2012-04-09 12:35:29

回答

12

你非常接近。

async void OnTestLoaded(object sender, RoutedEventArgs e) 
{ 
    await Task.Run(() => LongOperation()); 
} 

asyncdoes not execute a method on a thread pool thread

Task.Run对线程池线程执行操作,并返回表示该操作的Task

如果您在async方法中使用Task.Wait,那么您的是doing it wrong。你应该在async方法await任务,永远不会阻止他们。

+0

如果您在此特定示例中没有使用异步或等待,会有什么区别吗? – Lukazoid 2014-11-21 13:03:47

+0

@Lukazoid:如果你的意思只是'Task.Run'而没有'等待'它,那么这会默默吞下'LongOperation'中的所有异常。 – 2014-11-21 13:06:44

+0

但是不会因为'OnTestLoaded'是一个'async void'而吞噬异常吗?嗯,从进一步阅读看来,当使用异步无效时,异常将重新开始捕获的'SynchronizationContext',没有async/await,它会被吞噬,就像你说的那样,是正确的吗? – Lukazoid 2014-11-21 13:27:01

相关问题