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

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

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

为此,我阅读了thisthisthis,这就是我所拥有的:

    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(在我停止之前)。 我不认为这是正常的:)

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

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

【问题讨论】:

  • 在一个大部分时间都在休眠的线程中执行此操作是可怕的。请改用计时器,最好是 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。参见例如这里:stackoverflow.com/a/22957974/1136211
  • 不要使用goto,除非你绝对必须。在你的情况下,你不必。它和while(true){} 一样,只是更臭。

标签: c# wpf multithreading memory


【解决方案1】:

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


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

您不会在Properties/Resources.resx 中使用位图资源,而是只需将图像文件添加到您的 Visual Studio 项目中,例如在名为“Images”的项目文件夹中。然后将这些文件Resource 的构建操作设置为例如此处显示:https://stackoverflow.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”是一本很棒的书。
猜你喜欢
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
相关资源
最近更新 更多