我有一个虚拟化的ListBox,其中有大量的GIF从HDD加载,循环播放。
我正在使用Grid,因为我打算在控件中添加更多内容,所以请坚持下去。
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;
}
}
答案 0 :(得分:1)
您可以尝试为MediaEnded
事件编写完整的方法,并在类的析构函数中为事件编写-=
。我猜这个事件是罪魁祸首,这可能导致物体无法妥善处理。
您还可以为ListBox设置VirtualizingStackPanel.IsVirtualizing="true"
以提高性能。在http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.isvirtualizing(v=vs.110).aspx