2012-12-06 25 views
1

我是新來做C#Windows Phone編程。更好的方式來在Windows Phone上同步加載圖像?

概括地說,我目前正在建設一個應用程序,將:

負載image A

負載image B

,然後加載image C

然後用這3個圖像做一些崗位處理。

我的圖像B和圖像C在項目中構建爲Content。 圖片A是從圖庫中選擇或通過相機拍攝的,或者我們可以簡單地假設圖片A是從獨立存儲加載的。

我遇到了一個我認爲是由異步圖像加載引起的問題。

這裏是我的代碼:

... 
// I intend to load the 3 pictures by calling the method: LoadImage(int id) and LoadCImage(); 

      else if (ListBox.SelectedIndex == 0) 
      { 
       Debug.WriteLine("Selected 0"); 
       PhotoProcessor pp = new PhotoProcessor(); 
       WriteableBitmap imageA = new WriteableBitmap(AImage); 
       WriteableBitmap imageB = LoadImage(0); 
       WriteableBitmap imageC = LoadCImage(); 
       WriteableBitmap mix = pp.Mix(pp.CalcAverageColour(0), imageA, imageB, imageC); 
       resultPic.Source = mix; 
      } 
... 

和:

private WriteableBitmap LoadImage(int id) 
     { 
      //String uriString = "/Assets/img0.jpg";    
      //BitmapImage img = new BitmapImage(new Uri(uriString, UriKind.Relative)); 
      BitmapImage img = new BitmapImage(); 
      img.CreateOptions = BitmapCreateOptions.None; 
      //img.SetSource(Application.GetResourceStream(new Uri("/Assets/facetemplate0.jpg", UriKind.Relative)).Stream); 
      img.UriSource = new Uri("/Assets/img" + id + ".jpg", UriKind.Relative); 

      //img.UriSource = new Uri(uriString, UriKind.Relative); 
      return new WriteableBitmap(img); 
     } 

     private WriteableBitmap LoadCImage() 
     { 
      //BitmapImage img = new BitmapImage(new Uri("/Assets/imgC.jpg", UriKind.Relative)); 
      BitmapImage bmp = new BitmapImage(); 
      bmp.CreateOptions = BitmapCreateOptions.None; 
      //img.SetSource(Application.GetResourceStream(new Uri("/Assets/imgC.jpg", UriKind.Relative)).Stream); 
      bmp.UriSource = new Uri("/Assets/imgC.jpg", UriKind.Relative); 
      return new WriteableBitmap(bmp); 
     } 

現在我的問題是:

當我試圖運行這段代碼,它會拋出一個空引用異常,這是因爲函數mix無法加載Image AB和C(加載這些圖像是異步的)。

我不知道是否有辦法讓我順序加載這些圖像,然後讓我把它們傳遞給mix函數?

我已經試過什麼:

  1. 通過檢查this great blog post,我能知道,確實有一些方法來同步加載圖像,但你可以在我的代碼中看到的,我試過像使用博客帖一樣使用SetSource(stream),但不幸的是我得到了相同的空引用異常。

  2. 我也想過EventHandler方法,但我不認爲它在這種情況下是個好主意。如果我實現EventHandler,它會是這樣的(僞代碼):

    imageA_Opened() 
    { 
    LoadImageB += imageB_Opened(); 
    } 
    
    imageB_Opened() 
    { 
    LoadImageC += imageC_Opened(); 
    } 
    
    imageC_Opened() 
    { 
    PhotoProcessor pp = new PhotoProcessor(); 
    pp.Mix(averageColour, A, B, C); 
    } 
    

我說得對不對?

回答

0

你不是假設能夠順序下載圖像。這肯定會更容易開發,但它不會有效,因爲您會長時間阻塞處理器,從而凍結您的應用程序。

我也想過EventHandler方法,但我不認爲它在這種情況下是個好主意。如果我實現EventHandler,它會像(僞代碼):

是的,它會按照你所描述的一般模式。這是解決這個問題的恰當方法。

+0

感謝您的快速反應。所以在我的僞代碼中的想法是更好的方法?通過使用3個'EventHandler's? – dumbfingers

+1

@ ss1271是的。 – Servy

+0

謝謝,我會嘗試。 – dumbfingers

2

Servy是在說你不應該阻止與同步調用的UI正確。

有了這樣說,我曾在一個WP7應用程序類似的要求。我使用「異步CTP」來添加寫入同步功能的功能,在等待下一次調用之前完成。我有API調用需要來自早期調用的數據才能正常工作。

我相信這包括在.NET 4.5和適用於WP8。

http://msdn.microsoft.com/en-ca/library/vstudio/hh191443.aspx

這裏是我寫的提取數據用於我的應用程序(請注意 「異步」 和 「等待」 關鍵字):

public async Task<bool> GetDefaultData() 
{ 
    try 
    { 
     _cancellation = new CancellationTokenSource(); 

     UpdateProgress(DateTime.Now + ": Download Started.\n"); 
     List<string> data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetBaseDataUriList()); 
     App._apiConnection.Done(data); 

     UpdateProgress(DateTime.Now + ": Countries: " + App._context.Countries.Count() + "\n"); 
     UpdateProgress(DateTime.Now + ": Regions: " + App._context.Regions.Count() + "\n"); 
     UpdateProgress(DateTime.Now + ": Income Levels: " + App._context.IncomeLevels.Count() + "\n"); 
     UpdateProgress(DateTime.Now + ": Indicators: " + App._context.Indicators.Count() + "\n"); 

     data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetCountryUriList("CA")); 
     App._apiConnection.Done(data); 
     UpdateProgress(DateTime.Now + ": CA Population: " + App._context.PopulationDatas.Count(c => c.Country.Iso2Code == "CA") + "\n"); 

     data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetCountryUriList("US")); 
     App._apiConnection.Done(data); 
     UpdateProgress(DateTime.Now + ": US Population: " + App._context.PopulationDatas.Count(c => c.Country.Iso2Code == "US") + "\n"); 

     data = await App._apiConnection.DoWorkAsync(_cancellation.Token, ApiInfo.GetCountryUriList("CN")); 
     App._apiConnection.Done(data); 
     UpdateProgress(DateTime.Now + ": CN Population: " + App._context.PopulationDatas.Count(c => c.Country.Iso2Code == "CN") + "\n"); 

     return true; 
    } 
    catch (OperationCanceledException) 
    { 
     MessageBox.Show("Operation Cancelled"); 
     return false; 



    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("getDefaultData Exception: " + ex.Message); 

     return false; 
    } 
} 
+0

歡呼的隊友,我現在正在爲一個WP7.5項目工作,其中的異步CTP有bug,不會讓我安裝它。稍後當項目移至WP8時,我會嘗試使用異步CTP。謝謝。 – dumbfingers

+0

我有這個問題。我卸載了所有修補程序,然後重新安裝了VS2010,Service Pack,然後是異步CTP。然後我重新應用了所有修補程序。然後它就像我的冠軍一樣工作。希望這可以幫助! –

+0

是的,謝謝你的建議。我對這個問題進行了一些搜索,並找到了類似的解決方案。但我現在在Windows 8下: - [ – dumbfingers