2016-03-08 2 views
0

Я использую MediaElement, чтобы показывать видеоклипы в цикле в течение длительного периода времени. Через некоторое время (часы для Win 7/4 GB RAM) программа аварийно завершает работу, за исключением типа «Недостаточно памяти». Я контролировал память, используемую во время игры с Process Explorer-Sysinternals, а также регистрировал ее с помощью методов System.Diagnostics.Process. Оба способа показывают постепенное увеличение используемой памяти.Как освободить память, используемую MediaElement

Вот код:

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 создается динамически, уничтожен (вместе со всеми отмена подписки на события и т. д.) после нескольких клипов и создание снова. Память все больше поглощалась.

Любые предложения будут оценены!

+0

Как вы "уничтожив" ваш MediaElement? Это элемент пользовательского интерфейса, и WPF делает ужасную работу GC'ing элементов пользовательского интерфейса. – Xcalibur37

+0

Пытался сделать Source = null в конце игры? Вы defintely shoud попробуйте. – EngineerSpock

+0

Вот как я «уничтожаю» объект MediaElement obejct (созданный программно, а не в XAML): MediaPlayer.Stop(); MediaPlayer.MediaEnded - = MediaPlayer_MediaEnded; MediaPlayer.MediaOpened - = MediaPlayer_MediaOpened; MediaPlayer.Close(); GridTest.Children.Remove (MediaPlayer); MediaPlayer = null; GC.Collect(); Если создается с привязкой свойство Source, также перед Close(): BindingOperations.ClearBinding (MediaPlayer, MediaElement.SourceProperty); – MDimitrov

ответ

0

Мое предложение сделать следующее:

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(); 
} 
+0

Пробовал также MediaPlayer.Stop(); MediaPlayer.Source = null; MediaPlayer.Close(); а затем переназначить Source в VideoControl_MediaEnded() без эффекта. – MDimitrov

+0

@MDimitrov Хммм, вы также можете попытаться присвоить значение null всему объекту MediaPlayer, а затем повторно установить его. – EngineerSpock

+0

Я тоже это сделал, написал об этом в комментарии выше, где описано, как я «уничтожил» объект. – MDimitrov

Смежные вопросы