繁体   English   中英

ListBox中的MediaElement导致内存泄漏

[英]MediaElement in ListBox causing Memory Leak

我有一个虚拟的ListBox,其中从硬盘加载了很多GIF,这些GIF循环播放。

我正在使用网格,因为我打算向控件中添加更多内容,因此请坚持使用它。

LongFileName是完整路径。

public class cThumbnail3 : System.Windows.Controls.Grid
{
   public string LongFileName
    {
        get { return (string)GetValue(LongFileNameProperty); }
        set { SetValue(LongFileNameProperty, value); }
    }
    public static readonly DependencyProperty LongFileNameProperty =
        DependencyProperty.Register("LongFileName", typeof(string), typeof(cThumbnail3), new PropertyMetadata(OnLongFileNameChanged));


    static void OnLongFileNameChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        cThumbnail3 t = obj as cThumbnail3;
        t.LoadAsGif();
    }

    private MediaElement ME;
    public void LoadAsGif()
    {
        ME = new MediaElement();
        ME.UnloadedBehavior = MediaState.Manual;
        Uri uri = new Uri(@"file://" + LongFileName);
        ME.Source = uri;
        ME.MediaEnded += (o, e) =>
            {
                ME.Position = new TimeSpan(0, 0, 1);
                ME.Play();
            };
        this.Children.Clear();
        this.Children.Add(ME);
    }
}

xaml现在很简单

<local:cThumbnail3 LongFileName="{Binding FullPath}" />

当我上下滚动列表框时,我正在监视内存使用情况。 每次查看商品时,都会创建新的cThumbnail3,并且商品从头开始播放。

问题是一段时间后内存消耗达到1.2GB,播放停止

编辑我还尝试了什么:不同地添加事件+当控件不在视图中时,卸载所有内容

private bool IsVisible { get; set; }

public void LoadAsGif()
{
   ME = new MediaElement();
   ME.UnloadedBehavior = MediaState.Manual;
   Uri uri = new Uri(@"file://" + LongFileName);
   ME.Source = uri;
   ME.MediaEnded += ME_MediaEnded;
}
private void ME_MediaEnded(object sender, RoutedEventArgs e)
{
  if (!IsVisible) return;
  ME.Position = new TimeSpan(0, 0, 1);
  ME.Play();
}

private PropertyChangedEventHandler propertyChanged;

public event PropertyChangedEventHandler PropertyChanged
{
    add
    {
        var wasAttached = propertyChanged != null;
        propertyChanged += value;
        var isAttached = propertyChanged != null;

        if (!wasAttached && isAttached)
            OnPropertyChangedAttached();
    }
    remove
    {
        var wasAttached = propertyChanged != null;
        propertyChanged -= value;
        var isAttached = propertyChanged != null;

        if (wasAttached && !isAttached)
        {
            OnPropertyChangedDetached();
        }
    }
}

void OnPropertyChangedAttached()
{
    IsVisible = true;
    if (ME != null)
        ME.Play();
}

void OnPropertyChangedDetached()
{
    IsVisible = false;
    if (ME != null)
    {
        ME.MediaEnded -= ME_MediaEnded;
        ME.Stop();
        ME.Close();
        ME.Source = null;
        ME = null;
    }
}

您可以尝试为MediaEnded事件编写一个完整的方法,并且可以在类的析构函数中MediaEnded事件编写-= 我想这是造成此事件无法正确处置的罪魁祸首。

您还可以为ListBox设置VirtualizingStackPanel.IsVirtualizing="true"以提高性能。 http://msdn.microsoft.com/zh-cn/library/system.windows.controls.virtualizingstackpanel.isvirtualizing(v=vs.110).aspx上查找有关它的更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM