异步函数使代码无效

时间:2015-09-23 10:36:49

标签: c# windows-10 c#-5.0 windows-10-mobile

首先,为标题道歉...我没有找到任何适合我的单一案例: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包含KeyURL,可将XML个文件下载到应用的每个页面。

要填充的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的构造函数使用MainPage作为Callback,使用类Properties来查找下载XML文件的URL。

当调用Properties.Load()是异步方法时会发生什么,然后执行剩余的行,当程序完成时,然后返回Load()并填充Dictionary }。 由于Home构造函数取决于Value Properties,我得到Exception

我试图创建async void分配不同的优先级来强制程序先运行一件事然后剩下的,但它也没有用。

所以,总结一下,我需要确保Properties首先填充 ,有人知道怎么做吗?

提前致谢!

1 个答案:

答案 0 :(得分:2)

Eva如果你想等到Load方法完成,你必须改变这个方法来返回一个任务。

public async Task LoadAsync(string uri)...

如果将代码放在页面的LoadedEventHandler中并使此方法异步,则更好。之后,您将能够等待Properties.Load方法。

如果要在构造函数中调用此方法,可以这样执行:

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

但是你必须要知道,如果在没有禁用上下文切换(ConfigureAwait)的情况下等待LoadAsync方法,就会出现死锁。