2016-03-08 2 views
0

J'utilise MediaElement pour afficher des clips vidéo dans une boucle pendant une longue période. Après un certain temps (heures pour Win 7/4 Go RAM) le programme se bloque à l'exception du type "Mémoire insuffisante". J'ai surveillé la mémoire utilisée lors de la lecture avec Process Explorer-Sysinternals et également enregistré en utilisant les méthodes System.Diagnostics.Process. Les deux façons montrent une augmentation progressive de la mémoire utilisée.Comment libérer la mémoire utilisée par MediaElement

Voici le code:

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; } } 

} 

J'ai aussi testé le cas lorsque l'objet MediaElement est créé de façon dynamique, détruite (en même temps que tous les désinscription d'événements, etc.) après plusieurs clips et créé à nouveau. La mémoire a été consommée de plus en plus souvent.

Toutes les suggestions seraient appréciées!

+0

Comment allez-vous "détruire" votre MediaElement? Ceci est un élément d'interface utilisateur et WPF fait un travail terrible GC'ing éléments d'interface utilisateur. – Xcalibur37

+0

Essayé de faire Source = null à la fin de la lecture? Vous devriez essayer. – EngineerSpock

+0

Voici comment je "détruis" le MediaElement obejct (créé par programmation, pas en XAML): MediaPlayer.Stop(); MediaPlayer.MediaEnded - = MediaPlayer_MediaEnded; MediaPlayer.MediaOpened - = MediaPlayer_MediaOpened; MediaPlayer.Close(); GridTest.Children.Remove (MediaPlayer); MediaPlayer = null; GC.Collect(); Si créé avec liaison la propriété Source, également avant Close(): BindingOperations.ClearBinding (MediaPlayer, MediaElement.SourceProperty); – MDimitrov

Répondre

0

Ma proposition est de faire ce qui suit:

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

Essayé aussi MediaPlayer.Stop(); MediaPlayer.Source = null; MediaPlayer.Close(); puis réaffecté Source dans VideoControl_MediaEnded() sans effet. – MDimitrov

+0

@MDimitrov Hmmm, vous pouvez également essayer d'assigner une valeur nulle à l'objet MediaPlayer entier, puis le réinstituer. – EngineerSpock

+0

J'ai aussi critiqué cela, écrit à ce sujet dans un commentaire ci-dessus où j'ai décrit comment j'ai "détruit" l'objet – MDimitrov