【问题标题】:Windows.Web.Http.HttpClient.getAsync(uri) is hanging an app up and not cancellingWindows.Web.Http.HttpClient.getAsync(uri) 正在挂起应用程序而不是取消
【发布时间】:2015-07-01 17:15:38
【问题描述】:

我已经在这个问题上纠结了几个小时,我一辈子都想不通:(

所以我使用 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

我将提供所需的任何额外信息,请在下方评论。

谢谢

【问题讨论】:

标签: c# windows-phone-8.1 async-await


【解决方案1】:

取消令牌没有像在所有 我一直在看的例子。我不知道我要去哪里 错了。

由于您的应用程序死锁,它不会起作用。我什至不确定它第二次是如何运行的。使用.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 上不可用,那么你需要重新考虑你在做什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 2013-02-04
    • 2013-08-23
    • 1970-01-01
    相关资源
    最近更新 更多