不确定如何释放winforms中函数引起的内存

ghhaqwfi  于 2023-02-05  发布在  其他
关注(0)|答案(1)|浏览(150)

我的问题是无法或不知道如何清除内存中被不再使用的图像(位图)淹没的内容。该函数的目的是每隔x秒将表单的背景更改为一个新图像。
内存使用将不可避免地溢出,它将崩溃。但即使当我改变到一个不同的窗口,我运行this. close()和内存使用仍然不断增加。
函数如下:

public async void WaitSomeTime(String[] favs, int time)
{
    while (true)
    {
        var rnd = new Random();
        favs = favs.OrderBy(item => rnd.Next()).ToArray();
        foreach (string fav in favs)
        {
            await Task.Delay(time);
            Image img = new Bitmap(fav);
            this.pictureBoxBG.Image = img;
        }
                

    }
}

到目前为止,我已经尝试了Dispose方法,但没有效果,我不完全理解它。我已经尝试了'using'语句,但这导致了Program.cs(入口点)中的错误。我确信这是一个简单的修复,但我没有主意,GPT3也没有很好的帮助,提前感谢。

jgzswidk

jgzswidk1#

使用Visual Studio中的诊断工具,我们可以了解当前代码在大约5分钟的时间内相对于进程内存的行为。更新设置为每秒大约10次,以提供测试负载。尽管我用于测试的图像文件不是很大,但对内存消耗的影响是明显的。

你可以尝试的一种方法是显式地处理图像,然后收集垃圾,在每个完整的favs列表中应用这个似乎是合理的,但是你会得到一般的漂移,可以在你选择的任何地方应用它。

  • 需要说明的是,关键的一步是Dispose前一个映像,GC将从那里开始处理它。但是如果您的目标是尽可能降低内存占用,那么这个“非常措施”允许您行使更多的控制。*
public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        pictureBoxBG.SizeMode = PictureBoxSizeMode.StretchImage;
        string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");
        string[] favs = Enumerable.Range(0, 10).Select(_=>Path.Combine(dir, $"image-{_}.png")).ToArray();
        _task = WaitSomeTime(favs, 100);
    }
    Task _task;
    Random rnd = new Random();
    public async Task WaitSomeTime(String[] favs, int time)
    {
        while (true)
        {
            List<Image> trash= new List<Image>();
            favs = favs.OrderBy(item => rnd.Next()).ToArray();
            foreach (string fav in favs)
            {
                await Task.Delay(time);
                if(pictureBoxBG.Image != null)
                {
                    trash.Add(pictureBoxBG.Image);
                }
                Image img = new Bitmap(fav);
                pictureBoxBG.Image = img;
            }
            for (int i = 0; i < trash.Count; i++)
            {
                trash[i].Dispose();
                trash[i] = null;
            }
            // Requesting an expedited disposal of managed memory.
            GC.Collect();
        }
    }
}

相关问题