2014-11-04 158 views
0

在我當前的項目中,我將某些對象的狀態存儲在XML文件中。由於我在WPF項目中工作,我需要使用異步方法來完成此操作。使同步代碼取決於異步代碼

因此,我在加載我的應用程序時遇到問題。我是從XML文件重新創建這些對象的狀態,這將不得不做異步,但我的內容取決於這些對象的狀態,在我的情況下,導致對象在我之前沒有完全實例化與他們合作。

簡而言之:我的同步方法取決於啓動我的應用程序時實例化我的對象的異步方法。

下面是一段代碼,顯示了我如何閱讀整個文件夾的xml文件並生成對象列表。

public List<Restaurant> restaurant = new List<Restaurant>(); 

public async void ReadRestaurantAsync() 
{ 
    IStorageFolder filesFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("folder"); 
    var storageFiles = await filesFolder.GetFilesAsync(); 

    foreach (var storageFile in storageFiles) 
    { 
     using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read)) 
     using (Stream inputStream = stream.AsStreamForRead()) 
     { 
      DataContractSerializer serializer = new DataContractSerializer(typeof (Restaurant)); 
      Restaurant objectRead = serializer.ReadObject(inputStream) as Restaurant; 
      restaurant.Add(objectRead); 
     } 
    } 
} 

現在,當我從我的調用的MainPage這個異步方法,我不能與對象餐廳的工作,因爲它並沒有被完全實例化。

我猜想在嘗試與Restaurant進行交互之前,我將不得不等待該方法完全執行,但這似乎也有點奇怪,因爲它毀掉了關於異步方法的整個想法。

回答

2

那麼,你想要await的異步代碼,而不是等待徹底。這會在您加載數據時保持GUI響應(並且可能會顯示加載消息,具體取決於加載需要多長時間)。

在同步方法調用異步方法和等待沒有意義。如果你這樣做,你可以首先使用同步方法,並節省開銷。你想一直是異步的(是的,這意味着你不想在例如構造函數中加載數據 - 但是你不應該這樣做)。

注意,您可以await在的WinForms/WPF事件處理得很好,所以得到滾動這些LoadDataBinding事件等

總之:當你發現有同步代碼等待異步代碼自己 - 你設計可能有缺陷。在任何情況下,它都表明你忽略了同步問題等,當你開始使用await時,它們並沒有消失 - 訪問全局變量仍然是一個非常糟糕的主意。相反,您希望任務返回一個值(在您的情況下,可枚舉爲Restaurant),並將這些值添加到UI線程中的全局列表(即,繼續返回到同步上下文)。現在,你實際上是,因爲你正在處理UI線程上的所有異步回調,但這可能是不必要的,事實上可能是一個愚蠢的開銷,使得加載需要更長的時間。

認爲異步。不要在旅途中停下來。

+0

謝謝!很好的解釋。 – Mathias 2014-11-04 09:56:24