Как освободить память, используемую MediaElement
Я использую MediaElement для показа видеоклипов в цикле в течение длительного периода времени. Через некоторое время (часы для Win 7 / 4 ГБ ОЗУ) программа вылетает за исключением типа "Недостаточно памяти". Я отслеживал объем памяти, используемой во время игры с Process Explorer-Sysinternals, а также регистрировал ее с помощью методов System.Diagnostics.Process. Оба способа показывают постепенное увеличение используемой памяти.
Вот код:
XAML:
<Grid Name="GridTest">
<MediaElement x:Name="MediaPlayer"
LoadedBehavior="Manual"
MediaEnded="VideoControl_MediaEnded"
MediaOpened="MediaPlayer_MediaOpened"
Source="{Binding Mode=OneWay,
Path=MySource}" />
</Grid>
.cs:
public partial class MainWindow : Window
{
public MainViewModel model = new MainViewModel();
public MainWindow()
{
InitializeComponent();
this.GridTest.DataContext = model;
// fill in model.MediaFilesUris:
...
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// choose the next media file
...
MediaPlayer.Play();
}
private void VideoControl_MediaEnded(object sender, RoutedEventArgs e)
{
// choose the next media file
...
model.OnPropertyChanged("MySource");
MediaPlayer.Play();
}
}
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public Uri[] MediaFilesUris = null;
public int crn = 0;
public Uri MySource { get { if (MediaFilesUris != null && MediaFilesUris.Count()>0) return MediaFilesUris[crn]; else return null; } }
}
Я также протестировал случай, когда объект MediaElement создается динамически, уничтожается (вместе со всеми отписками от событий и т. Д.) После нескольких клипов и создается снова. Память снова расходуется.
Мы ценим любые предложения!
1 ответ
Попробуйте указать MediaElement UnloadingBehavior="Close"
свойство в вашем XAML.
Согласно MSDN MediaState::Close
указывает, что
Освобождаются все медиаресурсы (включая видеопамять).
Мое предложение сделать следующее:
private void VideoControl_MediaEnded(object sender, RoutedEventArgs e)
{
// choose the next media file
...
//make the following explicitly
MediaPlayer.Stop();
MediaPlayer.Source = null;
model.OnPropertyChanged("MySource");
MediaPlayer.Play();
}