Не могу найти утечку памяти

328
01 мая 2017, 00:09

Приложение получает изображение от клиента по UDP и пока что выводит его в Label.Background. Происходит утечка из за бесконечного цикла, но без него не представляю как постоянно получать пакеты. Как это можно устранить или правильно сделать?

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            mainRef = this;
            udpClient = new UdpClient(25565);
            GetData += new NetEvent(Receive_GetData);
            new AsyncWork(AsyncReceiver).BeginInvoke(null, null);
        }
        public static int countErorr = 0;
        public static MainWindow mainRef;
        private IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 25565);
        private UdpClient udpClient;
        private delegate void NetEvent(byte[] Date);
        private delegate void AsyncWork();
        private event NetEvent GetData;
        private void AsyncReceiver()
        {
            while (true)
            {
                try
                {
                    MemoryStream memoryStream = new MemoryStream();
                    byte[] bytes = udpClient.Receive(ref ep);
                    memoryStream.Write(bytes, 2, bytes.Length - 2);
                    int countMsg = bytes[0] - 1;
                    if (countMsg > 10)
                        throw new Exception("Не полный кадр");
                    else
                    {
                        for (int i = 0; i < countMsg; i++)
                        {
                            byte[] bt = udpClient.Receive(ref ep);
                            memoryStream.Write(bt, 0, bt.Length);
                        }
                        GetData(memoryStream.ToArray());
                        memoryStream.Close();
                    }                    
                }
                catch
                {
                    countErorr++;
                    mainRef.Dispatcher.BeginInvoke(new Action(() => { mainRef.label.Content = countErorr; } ));
                }
            }
        }
        private void Receive_GetData(byte[] Date)
        {
            if (ConvertToBrush(Date) != null)
            {
                mainRef.Dispatcher.BeginInvoke(new Action(() =>
                {
                    mainRef.label.Background = ConvertToBrush(Date);
                }
                ));
            }
        }
        private Brush ConvertToBrush(byte[] bytes)
        {
            MemoryStream memoryStream = new MemoryStream(bytes);
            try
            {
                System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(memoryStream);
                memoryStream = new MemoryStream();
                bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
                var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                return new ImageBrush(bitmapSource);
            }
            catch { }
            return null;
        }        
    }
Answer 1

Действительно, проблема была не в цикле, а в Bitmap, так и не удалось его правильно освобождать, поэтому заменил Label на компонент WPF Image и следующий код решил проблему.

        public static ImageSource ByteToImage(byte[] bytes)
        {
            BitmapImage bitmapImg = new BitmapImage();
            MemoryStream memoryStream = new MemoryStream(bytes);
            bitmapImg.BeginInit();
            bitmapImg.StreamSource = memoryStream;
            bitmapImg.EndInit();
            ImageSource imgSrc = bitmapImg as ImageSource;
            return imgSrc;
        }
        private static void Receive_GetData(byte[] Date)
        {
            mainRef.Dispatcher.BeginInvoke(new Action(() =>
            {
                    mainRef.img.Source = ByteToImage(Date);
            }));
        }
READ ALSO
Как Extended WPF Toolkit добавить в ToolBox

Как Extended WPF Toolkit добавить в ToolBox

Скачал через NuGet Extended WPF Toolkit

319
Размер буфера FileStream

Размер буфера FileStream

Какой рекомендуемый размер буфера указывать при создании объекта в конструкторе?

273
События контролов в ASP.NET

События контролов в ASP.NET

Проблема в том, что событие Click не срабатывает (даже в назначенный метод не заходит)Метод Redirect формирует POST запрос и выполняет перенаправление...

241