这是我认为我确切知道发生了什么的事情之一,但是我无法想象如何在Windows Phone 8上修复它。我希望有两种方法可以通过http读取;一个同步和一个异步。目前正在从UI线程调用同步函数,但最终可能不会。 相关代码如下所示:
private static string result;
public static string load() {
Task task = loadAsync();
task.Wait;
return result;
}
public async static Task < string > loadAsync() {
...
result = await webClient.DownloadStringTaskAsync(uri);
}
我打算在调用Task.Wait()时,UI线程将等待读取完成;没关系 - 我希望UI暂停,直到读完成。但正如所写,我似乎正在创建一个死锁,所以一切都挂起,下载永远不会完成,大概永远不会开始。 task.wait()导致死锁是有道理的,所以我创建了以下Test类:
public static class Test
{
const string apiUrl = @"http://169.254.21.12:51428/api/Q";
private static WebClient webClient;
private static Uri uri;
private static string result;
public static string Load()
{
webClient = new WebClient();
webClient.Headers["Accept"] = "application/json";
uri = new Uri(apiUrl);
try
{
Task<string> task = webClient.DownloadStringTaskAsync(uri);
result = task.Result;
}
catch (Exception e) { result = null; }
return result;
}
这个类在VS13的WP8模拟器中运行,与本地IIS通信,也在同一个解决方案中作为单独的项目启动。我们到达'result ='行,但该行永远不会返回。我知道IIS正在运行且网络链接正常,因为我可以在手机中使用IE来访问URI。
答案 0 :(得分:1)
是的,您目前正在制造僵局。
您正在使用async / await,这意味着当DownloadStringTaskAsync
返回的任务完成时,将继续安排继续loadAsync
从它停止的位置继续,并返回UI线程
但是,该延续永远不会实际运行,因为UI线程忙于等待任务完成......并且该任务仅在继续运行后才能完成。死锁。
只是为了阻止UI线程,您根本不需要使用async
/ await
:
// Method name changed to follow .NET conventions.
public static string Load() {
WebClient webClient = ...;
Task<string> task = webClient.DownloadStringTaskAsync(uri);
return task.Result; // Result blocks, just like Wait().
}
答案 1 :(得分:1)
您看到deadlock issue that I describe in detail on my blog。
我希望有两种方法可以通过http读取;一个同步和一个异步。
那就是你的问题。下载HTTP资源是一种自然异步操作,因此它应该只有一个异步API。