0

我非常感謝如何正確執行此操作的反饋意見。數據綁定異步數據加載和backgroundWorker

我在WP8有4個項目的全景視圖。一項是從Azure移動服務下載的地圖元素和其餘3個顯示數據。在主頁面代碼後面我設置了backgroundWorker和相關事件

private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     App.ViewModel.LoadData(); 
     System.Threading.Thread.Sleep(3000); 
    } 

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     RefreshBinding(); 
    } 

而在MainViewModel.cs中我有LoadData方法。

public async void LoadData() 
    {   
     PanItem1 = await PanItem1Table.ToCollectionAsync<PanItem1>(); 
     PanItem2 = await PanItem2Table.ToCollectionAsync<PanItem2>(); 
     PanItem3 = await PanItem3Table.ToCollectionAsync<PanItem3>(); 
    } 

RefreshBinding()只是相應地將3個panoramaItems的ItemSources設置爲PanItem1-3。出於某種原因,綁定在數據加載之前創建/綁定頁面時會自動失敗,並且之後必須重新設置ItemSource。

好吧,這看起來相當不錯,但在實踐中,我遇到了2個細節,導致我的麻煩。

1)bw_RunWorkerCompleted()立即被調用,它不會等待異步操作完成(我認爲它會)。我不得不在doWork()中添加人工睡眠(3000)。這遠不是最佳的,因爲我不確定數據是否在3秒後填充。

有沒有更好的方法來做到這一點?你能以某種方式驗證異步操作的完成嗎?

2)由於某些原因,偶爾全部失敗,應用程序完全空白。只顯示背景圖片和標題,並且每個panoramaItem的所有內容都是空的,並且地圖也無法完全加載。

我懷疑這是由於一次嘗試做太多事情造成的。如何平衡工作量有沒有一個簡潔的解決方案?我現在最好的猜測是使用全景的SelectionChanged事件並僅下載用戶當前正在查看的數據。這是做到這一點的正確方法嗎?

+0

我開始獲得一種感覺BackgroundWorker的是錯誤的做法。它似乎沒有增加任何東西,但程序中不必要的複雜性。 – Sopuli

回答

1

首先,你寫你的LoadData錯誤,你應該寫這樣的:

public async Task LoadDataAsync() 
{   
    PanItem1 = await PanItem1Table.ToCollectionAsync<PanItem1>(); 
    PanItem2 = await PanItem2Table.ToCollectionAsync<PanItem2>(); 
    PanItem3 = await PanItem3Table.ToCollectionAsync<PanItem3>(); 
} 

現在重寫調用函數:

private void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker worker = sender as BackgroundWorker; 
    App.ViewModel.LoadData().Wait(); 
    System.Threading.Thread.Sleep(3000); 
} 

這樣你實際上將等待異步操作去完成。但是,這仍然是錯的,你實際上應該拋棄整個BackgroundWorker,只需使用異步操作:

public async Task LoadDataAsync() 
{   
    PanItem1 = await PanItem1Table.ToCollectionAsync<PanItem1>(); 
    PanItem2 = await PanItem2Table.ToCollectionAsync<PanItem2>(); 
    PanItem3 = await PanItem3Table.ToCollectionAsync<PanItem3>(); 
    RefreshBinding(); 
} 
+0

Noob問題。由於LoadDataAsync在viewmodel中,並且RefreshBinding在MainPage中,我該如何撥打電話?添加這樣的依賴性不是不好的做法嗎? – Sopuli