新线程内存使用量不会停止增加

Posted

技术标签:

【中文标题】新线程内存使用量不会停止增加【英文标题】:New thread memory usage won't stop increase 【发布时间】:2021-05-02 02:46:51 【问题描述】:

我最近发现了如何在后台执行任务,并尝试在 WPF 中使用这些进行测试。

我尝试测试的是在图片框中创建图片轮播。

为此,我阅读了this、this 和this,这就是我所拥有的:

    public partial class Page2 : Page
    
        public Thread backgroundcaroussel;
        public Page2()
        
            InitializeComponent();
            backgroundcaroussel = new Thread(ImgFlip);
            backgroundcaroussel.IsBackground = true;
            backgroundcaroussel.Start();
        

        private void Button_Click(object sender, RoutedEventArgs e)
        
            backgroundcaroussel.Abort();
            MainWindow.Fenetre.Content = MainWindow.pgUn;
        

        private void ImgFlip()
        
        Again:

            this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (ThreadStart)delegate ()
            
                BitmapSource btmSrc1 = Imaging.CreateBitmapSourceFromHBitmap(Properties.Resources._1080p_1.GetHbitmap(),
                        IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                img_moins.Source = btmSrc1;
            );
            Thread.Sleep(2000);

            this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,(ThreadStart)delegate ()
            
                BitmapSource btmSrc2 = Imaging.CreateBitmapSourceFromHBitmap(Properties.Resources._1080p_2.GetHbitmap(),
                        IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                img_moins.Source = btmSrc2;
            );
            Thread.Sleep(2000);

            this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (ThreadStart)delegate ()
            
                BitmapSource btmSrc3 = Imaging.CreateBitmapSourceFromHBitmap(Properties.Resources._1080p_3.GetHbitmap(),
                        IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                img_moins.Source = btmSrc3;
            );
            Thread.Sleep(2000);
            goto Again;
        

    

当我使用此代码时,内存使用量不会停止增加并达到 1 或 2 Go(在我停止之前)。 我不认为这是正常的:)

我还阅读了this、this 和this 来解决问题,但不清楚该怎么做。

如何解决这种内存消耗? 我是否使用了正确的方法?

【问题讨论】:

在一个大部分时间都在休眠的线程中执行此操作是可怕的。请改用计时器,最好是 DispatcherTimer。但是感谢您向我们展示goto 仍然存在。您应该阅读一本介绍性 C# 的书,然后可能是一本关于 WPF 的书。 请注意,尽管在 UI 线程中调用了 DispatcherTimer 的 Tick 事件,但您仍然可以声明 Tick 处理程序方法 async 并运行创建 BitmapSource 的后台任务。 您经常调用Bitmap.GetHbitmap 方法。如果你看一下文档,你可以找到一个小注释:YOU是负责调用GDI DeleteObject方法来释放GDI位图对象使用的内存” 另外说明,您通常不会从Properties.Resources 中的System.Drawing.Bitmap 资源加载位图。相反,将图像文件添加到 Visual Studio 项目,将其构建操作设置为资源并从程序集资源包 URI 加载 BitmapImages。参见例如这里:***.com/a/22957974/1136211 不要使用goto,除非你绝对必须。在你的情况下,你不必。它和while(true) 一样,只是更臭。 【参考方案1】:

代码中内存消耗增加的问题是您必须通过调用DeleteObject 来删除GetHbitmap 返回的句柄,例如如此处所述:https://***.com/a/5827468/1136211


除此之外,在 WPF 应用程序中,您会以完全不同的方式实现整个逻辑。

您不会在Properties/Resources.resx 中使用位图资源,而是只需将图像文件添加到您的 Visual Studio 项目中,例如在名为“Images”的项目文件夹中。然后将这些文件Resource 的构建操作设置为例如此处显示:https://***.com/a/12693661/1136211

在启动时,将所有这些图像资源加载到一个列表中。然后启动一个 DispatcherTimer,将它们循环分配给 Image 元素的 Source 属性。

public partial class MainWindow : Window

    private readonly List<ImageSource> images = new List<ImageSource>();
    private int imageIndex;

    public MainWindow()
    
        InitializeComponent();

        images.Add(new BitmapImage(new Uri("pack://application:,,,/Images/Image1.png")));
        images.Add(new BitmapImage(new Uri("pack://application:,,,/Images/Image2.png")));
        images.Add(new BitmapImage(new Uri("pack://application:,,,/Images/Image3.png")));

        ShowNextImage();

        var timer = new DispatcherTimer  Interval = TimeSpan.FromSeconds(2) ;
        timer.Tick += TimerTick;
        timer.Start();
    

    private void TimerTick(object sender, EventArgs e)
    
        ShowNextImage();
    

    private void ShowNextImage()
    
        image.Source = images[imageIndex];
        imageIndex = (imageIndex + 1) % images.Count;
    

【讨论】:

非常感谢!让我知道在哪里可以了解更多相关信息。我保证你会阅读有关 wpf 的书籍 :) Adan Nathan 的 IMO “WPF Unleashed”是一本很棒的书。

以上是关于新线程内存使用量不会停止增加的主要内容,如果未能解决你的问题,请参考以下文章

如何停止 redis 内存使用量随着连接数的增加而增加

多线程强调内存碎片吗?

httpd [apache 2.4] 内存泄漏问题

在 C++ 中使用 realloc

AlamofireImage 没有释放内存

对等体断开连接后未释放SSL内存