我的Windows Phone应用程序(使用MVVM)中的WebClient存在特定问题
private string _lastCurrencyRatesJson;
private bool _lastCurrencyRatesJsonLoaded = false;
private void GetLastCoursesFromApiAsync()
{
var uri = new Uri(string.Format(OperationGetLastCourses, AppSettings.ApiEndpoint, AppSettings.ApiKey));
var client = new WebClient { Encoding = Encoding.UTF8 };
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(uri);
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
_lastCurrencyRatesJson = e.Result;
_lastCurrencyRatesJsonLoaded = true;
}
public List<CurrencyRate> GetLastCourses()
{
var worker = new Thread(GetLastCoursesFromApiAsync);
worker.Start();
while (!_lastCurrencyRatesJsonLoaded)
{
}
.....
问题是client_DownloadStringCompleted永远不会被解雇但是当我以这种方式更改GetLastCourses时:
public List<CurrencyRate> GetLastCourses()
{
var worker = new Thread(GetLastCoursesFromApiAsync);
worker.Start();
// whetever here, but any while...
触发client_DownloadStringCompleted并获取数据。这意味着,连接是可以的。
我遇到与DownloadStringTaskAsyn非常相似的问题。例如:
private async Task<string> GetCoursesForDayFromApiAsJson(DateTime date)
{
var uri = new Uri(string.Format(OperationGetCoursesForDay, AppSettings.ApiEndpoint, AppSettings.ApiKey, date.ToString(DateFormat)));
var client = new WebClient { Encoding = Encoding.UTF8 };
return await client.DownloadStringTaskAsync(uri);
}
同样,在await的行是等待数据的应用程序,但是DownloadStringTaskAsync永远不会完成,我的UI仍在加载。
任何想法可能出错?
状况一天 因此,看起来WP应用程序只使用一个线程。这意味着,当前线程必须“完成”,然后完成DownloadStringTaskAsync并执行await下的代码。当我想使用Task.Result我不能。从不。
当我创建另一个Thread而我正在尝试等待线程完成时(使用Join()),创建的Thread永远不会被finsihed,并且从不执行Join()之后的代码。
互联网上有任何一个例子,我绝对不知道,为什么存在一些不适用的DownloadStringTaskAsync。
答案 0 :(得分:2)
您正在通过while
循环阻止UI线程,同时,DownloadStringCompleted
事件想要在UI循环上执行。这会导致死锁,所以没有任何反应。你需要做的是让GetLastCourses()
返回(以及调用它的任何方法),以便事件处理程序可以执行。这意味着处理结果的代码应该在该事件处理程序中(不在GetLastCourses()
)。
使用async
- await
,您没有提供所有代码,但通过调用Wait()
或{{1}可能会遇到几乎相同的问题在返回的Result
上。如果用Task
替换它,您的代码将起作用。虽然这需要您从await
向上GetCoursesForDayFromApiAsJson()
生成所有代码。
答案 1 :(得分:0)
我建议使用HttpClient class from Microsoft NuGet package并使用async / await下载模式,而不是使用基于事件的WebClient类:
Uri uri = new Uri(string.Format(OperationGetLastCourses, AppSettings.ApiEndpoint, AppSettings.ApiKey));
using (HttpClient client = new HttpClient())
{
string result = await client.GetStringAsync(uri);
}