异步函数使代码不起作用
Async Functions making code not working
首先,为标题向我道歉...我还没有找到适合我的单一案例的:P
首先我需要下载一个INI
文件来填充Dictionary
。为此,我有这个 class:
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
包含一个 Key
和一个 URL
,用于将 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
和 class Properties
来寻找 URL下载 XML
文件。
发生的事情是,因为 Properties.Load()
是一个异步方法,被调用,然后执行剩余的行,当程序完成时,然后返回到 Load()
并填充 Dictionary
。
由于 Home
构造函数依赖于 Properties
的 Value
我得到一个 Exception
.
我已经尝试创建 async void
s 分配不同的优先级以强制程序先 运行 一件事然后是其余的,但它也没有奏效。
所以,总结一下,我需要确保Properties
首先被填充,谁知道怎么做?
提前致谢!
Eva 如果您想等到 Load 方法完成,您必须将此方法更改为 return 任务。
public async Task LoadAsync(string uri)...
最好将代码放在页面的 LoadedEventHandler 中并使此方法异步。之后,您将能够等待 Properties.Load 方法。
如果你想在构造函数中调用这个方法,你可以这样做:
Task.Run(async () =>{
var task = p.LoadAsync().ConfigureAwait(false);
await task;
}).Wait()
但您必须注意,如果在没有禁用上下文切换 (ConfigureAwait) 的情况下等待 LoadAsync 方法,则可能会出现死锁。
首先,为标题向我道歉...我还没有找到适合我的单一案例的:P
首先我需要下载一个INI
文件来填充Dictionary
。为此,我有这个 class:
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
包含一个 Key
和一个 URL
,用于将 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
和 class Properties
来寻找 URL下载 XML
文件。
发生的事情是,因为 Properties.Load()
是一个异步方法,被调用,然后执行剩余的行,当程序完成时,然后返回到 Load()
并填充 Dictionary
。
由于 Home
构造函数依赖于 Properties
的 Value
我得到一个 Exception
.
我已经尝试创建 async void
s 分配不同的优先级以强制程序先 运行 一件事然后是其余的,但它也没有奏效。
所以,总结一下,我需要确保Properties
首先被填充,谁知道怎么做?
提前致谢!
Eva 如果您想等到 Load 方法完成,您必须将此方法更改为 return 任务。
public async Task LoadAsync(string uri)...
最好将代码放在页面的 LoadedEventHandler 中并使此方法异步。之后,您将能够等待 Properties.Load 方法。
如果你想在构造函数中调用这个方法,你可以这样做:
Task.Run(async () =>{
var task = p.LoadAsync().ConfigureAwait(false);
await task;
}).Wait()
但您必须注意,如果在没有禁用上下文切换 (ConfigureAwait) 的情况下等待 LoadAsync 方法,则可能会出现死锁。