简体   繁体   English

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

[英]HttpClient.GetAsync(…) “deadlock” when there is no internet connection

Recenly I found some sort of bug while using System.Net.http.HttpClient().GetAsync(...) 我在使用System.Net.http.HttpClient()时发现了一些错误.GetAsync(...)

When in the middle process of GetAsync(..) , if I disconnect my internet connection, the app just act like deadlock, and no exception catch, even I wait for few minutes. 当在GetAsync(..)的中间过程中,如果我断开我的互联网连接,应用程序就像死锁一样,没有异常捕获,即使我等待几分钟。

Here is the example of code: 以下是代码示例:

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;
    }
}

I had try to set timeout to the httpClient, but it won't care what I set if there is no internet connection. 我曾尝试将超时设置为httpClient,但如果没有互联网连接,它将不关心我设置的内容。

Is there any way to catch if the internet connection is disconnected, or did I miss something? 如果互联网连接断开,或者我错过了什么,有什么方法可以捕获吗?

Edit: another async task that await loadImageAsync(..) 编辑:另一个异步任务,等待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;
    }
}

have you tried setting timeout with CancelationToken? 你试过用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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM