Недостаточно памяти C # freezable.freeze - PullRequest
0 голосов
/ 07 декабря 2010

Я пытаюсь скопировать некоторые изображения в ОЗУ, но это приводит к исключению нехватки памяти .. Я не знаю почему, но я думаю, что это причина "замораживания ()". Но как «разморозить», и действительно ли это проблема?

        public void preLoadThread(Object o)
    {
        Overlay ov = (Overlay)o;
        ImageSource tempNext = BitmapConverter(ov.tempPreLoadPathNext);
        ImageSource tempPrev = BitmapConverter(ov.tempPreLoadPathPrev);
        tempNext.Freeze();
        tempPrev.Freeze();
        ov.Dispatcher.Invoke(
            DispatcherPriority.Normal,
            (Action)delegate()
            {
                ov.preLoadedNext = tempNext;
                ov.preLoadedPrev = tempPrev;
                ov.preLoadPathNext = ov.tempPreLoadPathNext;
                ov.preLoadPathPrev = ov.tempPreLoadPathPrev;
            }
        );
    }

    public BitmapSource BitmapConverter(String path)
    {
        System.Drawing.Bitmap b = null;
        using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite))
        {
            try
            {
                b = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(fs);
            }
            catch (Exception)
            {
                GC.Collect();
                GC.WaitForFullGCComplete();
            }
            fs.Close();
        }

        if ( b == null)
        {
            // Error
            return null;
        }

        BitmapSizeOptions options = BitmapSizeOptions.FromEmptyOptions();
        BitmapSource bs = null;
        try
        {
            bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
               b.GetHbitmap(),
               IntPtr.Zero,
               Int32Rect.Empty,
               options);
        }
        catch (Exception)
        {
            GC.Collect();
            GC.WaitForFullGCComplete();
        }
        return bs;
    }

Ответы [ 2 ]

1 голос
/ 08 декабря 2010

Я искренне сомневаюсь, что исключение памяти исходит от вызова Freeze (), поскольку это действительно не выделяет память.

Я почти уверен, что у вас есть утечка GDI ... Вы должнывызовите DeleteObject для растрового изображения, которое вы создаете после вызова CreateBitmapSourceFromHBitmap () ... но поскольку вы вызываете GetHbitmap () в качестве параметра, у вас нет дескриптора для удаления.

Попробуйте это:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

IntPtr hObject = b.GetHbitmap();
bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
           hObject,
           IntPtr.Zero,
           Int32Rect.Empty,
           options);

DeleteObject(hObject);

Хенк прав, вы не должны форсировать коллекцию GC ... это на самом деле не помогает вам, потому что вы все равно не освобождаете что-либо, что нужно собрать (единственное, что вы освобождаете - это очищать с помощью DeleteObject().

О скольких изображениях 1378x2000 мы говорим? Даже если вы исправите утечку GDI, это большие картинки, которые быстро поглотят память.Разморозить, вы должны клонировать ... но вы будете выделять память, когда будете делать это. Просто чтобы предупредить вас.

Полагаю, что запуск под 64-битной версией невозможен ...

0 голосов
/ 07 декабря 2010

Что касается вашего вопроса "разморозить", вы не можете на начальном предмете, но вы можете выделить незамерзающий клон, подробности и пример на MSDN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...