我已经坚持这个问题几个小时了,我无法弄清楚我的生活:(
所以我正在使用HttpClient来访问我在我的应用程序中使用的网站上托管的XML文件。
我尝试过CancellationTokens无济于事,无法找到进一步调试此问题的方法。
我的功能如下:
public static async Task<string> GetXML()
{
string xml = string.Empty;
Uri url = new Uri("http:/blabla.com/CompanyAppsManifest.xml");
HttpClient hCli = new HttpClient();
CancellationTokenSource cts = new CancellationTokenSource(7000);
hCli.DefaultRequestHeaders.TryAppendWithoutValidation("Accept-Encoding", "UTF-8");
hCli.DefaultRequestHeaders.TryAppendWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml, charset=utf-8, text/xml");
try
{
var response = await hCli.GetAsync(url).AsTask(cts.Token);
if (response.IsSuccessStatusCode == true)
{
xml = response.Content.ToString();
hCli.Dispose();
return xml;
}
else
{
hCli.Dispose();
MessageBox.Show("Contact the admin with this info: SC: " + response.StatusCode.ToString() + " Content: " + response.Content.ToString());
if (Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
Debugger.Break();
}
xml = "Operation failed due to: HTTP Failure";
return xml;
}
}
catch (OperationCanceledException)
{
MessageBox.Show("Operation failed to complete in a timely fashion, please ensure you have WiFi active or a stable data connection");
xml = "Operation failed due to timeout";
return xml;
}
catch (Exception ex)
{
MessageBox.Show("error" + ex.Message + " : " + ex.InnerException.Message);
xml = "Operation failed due to exception";
return xml;
}
finally
{
cts = null;
}
}
它是从公共类上的一个方法调用的,它的返回类型为IEnumerable,但它没有被标记为异步方法。
该方法从我的方法中获取字符串,如此
var ss = GetXML().Result;
任何人都可以告诉我为什么
1:取消令牌在我看过的所有示例中似乎都没有起作用。我无法弄清楚我哪里出错了。
和2.它似乎只在第一次运行时冻结应用程序,如果它在第一次运行时冻结然后关闭应用程序并重新启动它,则getAsync方法运行正常并且程序按预期运行。
任何帮助或建议都将不胜感激,因为我找不到任何可以帮助我的东西:(
这个问题与此问题非常相似:How to debug app hanging on Windows Phone 8.1
我将提供以下评论所需的任何额外信息。
谢谢
答案 0 :(得分:2)
取消令牌并不像所有人一样正常运作 我一直在关注的例子。我无法弄清楚我要去哪里 错。
它不起作用,因为你的应用程序死锁。我甚至不确定它是如何第二次运行的。使用.Result
阻止异步方法将导致死锁。此外,您需要使用GetAsync
重载,该重载需要CancellationToken
。请注意,即使你传递了一个令牌,如果这种情况发生僵局,它也不会起作用。
var response = await hCli.GetAsync(url, cts.Token).AsTask(cts.Token);
似乎只在第一次运行时冻结应用程序,如果它 当你第一次运行它然后关闭应用程序时冻结 重新启动它,getAsync方法运行正常,程序运行为 预期
我不确定这是怎么回事。如果你从UI线程调用它,它应该每次都会死锁。
Don't block no async code。相反,让它自然地流过你的代码库。如果您的方法无法使用async-await
并且必须阻止,请使用同步API。如果WP上没有这个功能,那么你需要重新思考你正在做什么。