当没有互联网连接时,HttpClient.GetAsync(...)“死锁”

时间:2016-08-17 15:06:56

标签: c# async-await uwp dotnet-httpclient

在使用 System.Net.http.HttpClient()时,我发现了一些错误.GetAsync(...)

当处于 GetAsync(..)的中间过程时,如果我断开了我的互联网连接,该应用就像死锁一样,没有异常捕获,即使我等了几分钟。

以下是代码示例:

private async Task<WriteableBitmap> loadImageAsync(string url)
{
    using (var httpClient = new HttpClient())
    {
        //When this line of code start execute, immediately disable the internet connection
        var response = await httpClient.GetAsync(url);

        //Once it get stuck at GetAsync(..), it won't execute the codes below
        byte[] imageByte = await response.Content.ReadAsByteArrayAsync();

        WriteableBitmap bitmap = new WriteableBitmap(1920, 1080);

        using (InMemoryRandomAccessStream randomStream = new InMemoryRandomAccessStream())
        {
            using (DataWriter writer = new DataWriter(randomStream))
            {
                writer.WriteBytes(imageByte);
                await writer.StoreAsync();
                await writer.FlushAsync();
                writer.DetachStream();
            }

            randomStream.Seek(0);

            await bitmap.SetSourceAsync(randomStream);
        }
        return bitmap;
    }
}

我曾尝试将超时设置为httpClient,但如果没有互联网连接则不会关心我设置的内容。

如果互联网连接断开,或者我错过了某些东西,有没有办法抓住?

编辑另一个异步任务,等待loadImageAsync(..)

public async Task GetImagesAsync()
{
    //skip if image is currently loading
    if (IsImageLoading) { return; }

    IsImageLoading = true;
    ImageObjs.Clear();

    try
    {
        int numberOfLoad = (int)((double)_LocalSettings.Values[NUMBER_OF_IMAGE_LOAD_SETTINGS]);
        string region = _LocalSettings.Values[REGION].ToString();

        #region Get Bing Image info
        string jsonString = await new HttpClient().GetStringAsync($"http://www.bing.com/HPImageArchive.aspx?format=js&n={numberOfLoad}&mkt={region}");
        ImageCollection imageCollection = JsonConvert.DeserializeObject<ImageCollection>(jsonString);
        #endregion

        #region Download images
        foreach (var i in imageCollection.images)
        {
            string url;

            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
            {
                url = i.url.Replace("1920x1080", "1080x1920");
            }
            else
            {
                url = i.url;
            }

            ImageObjs.Add(new ImageObj(await loadImageAsync(bingLink + url), i.copyright, url, i.copyrightlink, region));
        }

        showToastNotification(_MainViewModel.ImageObjs.Count.ToString() + " images loaded.");
        #endregion
    }
    catch
    {
        //if connection failed
    }
    finally
    {
        IsImageLoading = false;
    }
}

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用CancelationToken设置超时?

var tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromSeconds(15));

try
{
    var response = await httpClient.GetAsync(url, tokenSource.Token);
}
catch (TaskCanceledException ex)
{
    // handle timeout here
}