【问题标题】:HttpClient GetAsync fails in background task on Windows 8HttpClient GetAsync 在 Windows 8 上的后台任务中失败
【发布时间】:2012-10-25 23:03:39
【问题描述】:

我有一个 Win RT 应用程序,它有一个后台任务,负责调用 API 来检索需要更新自身的数据。但是,我遇到了一个问题;在后台任务之外运行时,调用 API 的请求可以完美运行。在后台任务内部,它会失败,并且还会隐藏任何可能有助于指出问题的异常。

我通过调试器跟踪这个问题以跟踪问题点,并验证执行在 GetAsync 上停止。 (我传递的 URL 是有效的,并且 URL 响应不到一秒)

var client = new HttpClient("http://www.some-base-url.com/");

try
{
    response = await client.GetAsync("valid-url");

    // Never gets here
    Debug.WriteLine("Done!");
}
catch (Exception exception)
{
    // No exception is thrown, never gets here
    Debug.WriteLine("Das Exception! " + exception);
}

我读过的所有文档都说后台任务可以根据需要拥有尽可能多的网络流量(当然是节流的)。所以,我不明白为什么这会失败,或者知道任何其他诊断问题的方法。我错过了什么?


更新/回答

感谢 Steven,他为问题指明了方向。为了确保确定的答案存在,这里是修复前后的后台任务:

之前

public void Run(IBackgroundTaskInstance taskInstance)
{
    BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

    Update();

    deferral.Complete();
}

public async void Update()
{
    ...
}

之后

public async void Run(IBackgroundTaskInstance taskInstance) // added 'async'
{
    BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

    await Update(); // added 'await'

    deferral.Complete();
}

public async Task Update() // 'void' changed to 'Task'
{
    ...
}

【问题讨论】:

    标签: c# windows-8 windows-runtime background-process


    【解决方案1】:

    当你的Task 完成时,你必须调用IBackgroundTaskInterface.GetDeferral 然后调用它的Complete 方法。

    【讨论】:

    • 上面的代码在GetDeferral()和defarral.Complete()的中间。当 GetAsync() 失败时,部分问题是它还阻止了 Complete() 被调用
    • 您需要先await,然后再调用Complete。这样一来,Complete 在完成之后被调用
    • 您说的完全正确,后台任务正在调用async void 方法,但没有正确等待它。谢谢
    • P.S.作为一般规则,请避免使用async void。您应该始终使用async Task 而不是async void,除非您必须使用async void
    【解决方案2】:

    以下是我的做法,它对我有用

            // Create a New HttpClient object.
            var handler = new HttpClientHandler {AllowAutoRedirect = false};
            var client = new HttpClient(handler);
            client.DefaultRequestHeaders.Add("user-agent",
                                             "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
    
            var response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
    

    【讨论】:

    • 后台任务?你是什​​么意思? BackgroundWorker?
    • 不,我没有使用 BackgroundTask,很抱歉造成混淆
    猜你喜欢
    • 2016-04-20
    • 2015-08-04
    • 1970-01-01
    • 2017-11-03
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多