タスクを使用します ( AsyncCtp with Silverlight 4 ):
public void Load(){
this.IsBusy = true;
Task.Factory.StartNew(()=> DoHeavyWork())
.ContinueWith( t => this.IsBusy = false);
}
Async CTP またはVS2012/Silverlight 5で新しい async/await 機能を使用できると、さらに良くなります。
public async void Load(){
try{
this.IsBusy = true;
await Task.Factory.StartNew(()=> DoHeavyWork());
}
finally
{
this.IsBusy = false;
}
}
編集
バックグラウンド タスクで ObservableCollection を更新していると仮定します。コレクションの更新を処理するハンドラーは UI スレッドで実行されないため、実際には問題が発生します。そのため、バインディング システムのようにコレクションの更新はスレッド セーフではありません。これを機能させるには、UI スレッドで ObservableCollection にアイテムを追加する必要があります。一度にすべてのアイテムを取得できる場合は、次のようにすることができます。
public async void Load(){
try{
this.IsBusy = true;
// Returns the fetched items
var items = await Task.Factory.StartNew(()=> DoHeavyWork());
// This will happen in the UI thread because "await" returns the
// control to the original SynchronizationContext
foreach(var item in items)
this.observableCollection.Add(item);
}
finally
{
this.IsBusy = false;
}
}
バッチでロードする必要がある場合は、この回答で提案したように、現在の Dispatcher を使用してアイテムをコレクションに追加できます。