简体   繁体   中英

High memory usage with WebClient DownloadData

I have an issue memory not being released after webclient has downloaded data so I tested with the below sample code and it also happens with it. GC collects up to 10-20% of it but that still leaves way too much, I really have no idea what could be wrong as it appears nobody else is having problems with it.


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
    }

    private List<string> list = new List<string>();
    public void DownloadThumb(string Url)
    {
        WebClient ThumbClient = new WebClient();
        ThumbClient.DownloadDataCompleted += DownloadFinished;
        ThumbClient.DownloadDataAsync(new Uri(Url));
    }

    private int donecount = 0;
    public void DownloadFinished(object sender, DownloadDataCompletedEventArgs e)
    {
        Image DownloadedImage;
        using (MemoryStream MemoryStreamTemp = new MemoryStream(e.Result))
        {
            DownloadedImage = Image.FromStream(MemoryStreamTemp);
        }
        DownloadedImage.Dispose();
        ((WebClient)sender).Dispose();

        donecount++;
        if (donecount == list.Count)
        {
            donecount = 0;
            button1.Enabled = true;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;
        foreach (string TempString in list)
        {
            DownloadThumb(TempString);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        GC.Collect();
    }
}

在此处输入图像描述

The answer would be to change to HttpClient as WebClient is not meant to be used like that, and it's also older and basically obsolete.

With the following code memory usage is 60MB at start > 600 after download > 200 after GC > 70 at some later GC about 90s later.


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
        list.Add("https://media1.giphy.com/media/Uwj2CxFJs8ZyM/giphy.gif");
        list.Add("https://media0.giphy.com/media/5Ut5IWqO2kfDU1FG8T/giphy.gif");
    }

    //Becase https://qa.ostack.cn/qa/?qa=619128
    static HttpClientHandler handler = new HttpClientHandler();

    private List<string> list = new List<string>();
    static readonly HttpClient ThumbClient = new HttpClient(handler);
    public async Task<Image> DownloadThumb(string Url)
    {
        byte[] bytes = await ThumbClient.GetByteArrayAsync(new Uri(Url));
        Image DownloadedImage = (Image)new ImageConverter().ConvertFrom(bytes);
        return DownloadedImage;
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;
        List<Task<Image>> tasks = new List<Task<Image>>();
        list.ForEach(s => tasks.Add(DownloadThumb(s)));
        await Task.WhenAll(tasks);
        foreach (Task<Image> task in tasks)
        {
            task.Dispose();
        }
        button1.Enabled = true;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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