2012-04-08 13 views
6

UIをフリーズすることなく、バックグラウンドでアクションを実行しようとしています。UIをフリーズしないで長いタスクを実行する

もちろん、これにはBackgroundWorkerを使用できます。

しかし、私はタスク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

+0

'BackgroundWorker'は' Thread'よりはるかに優れていますが、最終的に 'Task'ベースのAPIが支配的になります。私は[関連するブログ記事](http://nitoprograms.blogspot.com/2010/08/various-implementations-of-asynchronous.html)を持っています。 'Task.Run'には次のような利点があります:(1)入れ子を許します。 (2)取り消しサポートは、統一された「CancellationToken」システムを使用する。 (3)例外は正しい呼び出しスタックでより自然に伝達されます。 (4)結果はより自然に取り出される。 (5)は、より少ないリソース(専用スレッドの代わりにスレッドプール)を使用します。 –

答えて

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の方法で行うべきです。

+0

この特定の例で非同期または待機を使用しなかった場合、違いはありますか? – Lukazoid

+0

@ルカゾイド: 'Task.Run'だけを' wait 'することなく意味するなら、 'LongOperation'からのすべての例外を静かに呑み込むでしょう。 –

+0

'OnTestLoaded'が' async void'なので例外を飲み込むことはありませんか?ああ、さらに読んで、async voidを使用すると、async/awaitなしで、開始時にキャプチャされた 'SynchronizationContext'で例外が再現されるようですが、それはあなたが言ったように飲み込まれるでしょう、それは正しいですか? – Lukazoid

関連する問題