2015-09-23 85 views
0

首先,我道歉爲標題...我還沒有發現任何相適應我的一個案例:P異步函數使代碼不工作

我需要下載一個文件INI填補Dictionary首先的。對於這一點,我有這個類:

public class Properties : INotifyPropertyChanged 
{ 
    private Dictionary<string, string> _properties; 

    public Properties() 
    { 
     _properties = new Dictionary<string, string>(); 
    } 

    public async void Load(string uri) 
    { 
     Stream input = await connection(uri); 

     StreamReader rStream = new StreamReader(input); 
     string line; 

     while((line = rStream.ReadLine()) != null) 
     { 
      if(line != "") 
      { 
       int pos = line.IndexOf('='); 
       string key = line.Substring(0, pos); 
       string value = line.Substring(pos + 1); 
       _properties.Add(key, value); 

       Debug.WriteLine("Key: " + key + ", Value: " + value); 
      } 
     } 

     Debug.WriteLine("Properties dictionary filled with " + _properties.Count + " items."); 
    } 

    public async Task<Stream> connection(string uri) 
    { 

     var httpClient = new HttpClient(); 

     Stream result = Stream.Null; 

     try 
     { 
      result = await httpClient.GetStreamAsync(uri); 

     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex.Message); 
      Debug.WriteLine(ex.HResult); 
     } 
     return result; 
    } 

    public string getValue(string key) 
    { 
     string result = ""; 
     try 
     { 
      result = _properties[key]; 
     } 
     catch(Exception ex) 
     { 
      Debug.WriteLine(ex.Message); 
      Debug.WriteLine(ex.HResult); 
      result = "Not found"; 
     } 
     return result; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void RaisePropertyChanged([CallerMemberName]string propertyName = "") 
    { 
     var Handler = PropertyChanged; 
     if (Handler != null) 
      Handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

}

主要的Dictionary包含KeyURLXML文件下載到應用程序的每個頁面。

MainPage,這是一個是要去填充有這樣的代碼:

public MainPage() 
    { 
     this.InitializeComponent(); 

     //Properties dictionary filling 
     prop = new Properties(); 
     prop.Load("URL"); 

     tab = new Bars.TopAppBar(); 
     bab = new Bars.BottomAppBar(); 

     tABar = this.topAppBar; 
     actvt = this.Activity; 
     bABar = this.bottomAppBar; 

     //Constructor of the UserControl 
     act = new Home(this, prop); 

    } 

UserControl的構造函數使用MainPageCallback和類Properties去尋找URL下載XML文件。

會發生什麼情況是,作爲Properties.Load()是一種異步方法,被調用,然後將剩餘的線被執行,並且程序完成時,然後回到Load()並填充Dictionary。 由於Home構造函數依賴於ValueProperties我得到一個Exception

我試圖創建async void s分配不同的優先級來強制程序運行第一件事,然後運行其餘的,但它也沒有工作。

因此,總結一下,我需要確保Properties填充在首位,任何人都知道如何做到這一點?

在此先感謝!

回答

2

Eva如果您想等到Load方法結束,您必須更改此方法以返回任務。

public async Task LoadAsync(string uri)... 

如果您將代碼放入頁面的LoadedEventHandler並使此方法異步,則更好。之後,您將能夠等待Properties.Load方法。

如果要調用構造函數這種方法,你可以做這樣的:

Task.Run(async() =>{ 
var task = p.LoadAsync().ConfigureAwait(false); 
await task; 
}).Wait() 

但是你必須要意識到,僵局可能出現如果LoadAsync方法沒有禁用上下文切換來等待(ConfigureAwait )。

+0

非常感謝@ razor118!我終於解決了這個問題:) –