Search code examples
c#wpfmediaelement

wpf MediaElement memory leak


I am using a media element to display several kinds of resources (image, gif, video)

The issue is that the media element will consume more memory each time I assign it a new source. The garbage collector is not collecting anything there. I have found several questions about the same topic in forums and on stack overflow but none of them received a proper answer.

So this my wpf code:

private void LoadInformation(FileInfo file)
{
    imageDisplay.Source = new Uri(file.FullName);
}

<MediaElement x:Name="imageDisplay" Grid.Column="0" Grid.Row="0" UnloadedBehavior="Close" LoadedBehavior="Manual"
            MediaOpened="Element_MediaOpened" MediaEnded="Element_MediaEnded" ></MediaElement>

this is my code to update in .xaml.xs:

// When the media opens, initialize the "Seek To" slider maximum value
// to the total number of miliseconds in the length of the media clip.
private void Element_MediaOpened(object sender, EventArgs e)
{
    imageDisplay.Play();
}

// When the media playback is finished. Stop() the media to seek to media start.
private void Element_MediaEnded(object sender, EventArgs e)
{
    imageDisplay.Stop();
    imageDisplay.Source = null;
}

This is according to official microsoft documentation: https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/how-to-control-a-mediaelement-play-pause-stop-volume-and-speed?view=netframeworkdesktop-4.8

if I execute LoadInformation in a loop, my memory goes up happily, until the application crashes.

If I stop the loop before the app crashes and let it run for a while, gc will not free up the memory enter image description here

Update 1

Managing the MediaElement Manually does not make any difference: LoadedBehavior = MediaState.Manual;

imageDisplay.Stop();
imageDisplay.Close();
imageDisplay.Source = null;
imageDisplay.Source = new Uri(file.FullName);
imageDisplay.Play();

enter image description here


Solution

  • After two days of searching and not finding ANY working solution, I found some hints at least.

    Issue:

    Take the following information with a huge grain of salt.

    What I think happened is that MediaElement is a Legacy component from Winforms wrapped in WPF. I have seen several hints such as the change of source from stream to uri. What caught my attention was that some methods such as mediaelement.Finalize() were removed.
    My best guess is that MediaElement simply should not be used nowadays anymore?

    Solution

    As seen in my screenshot above, a memory consumption of 64gb for displaying a 84kb jpg is indiscutable. I have searched around for alternatives.
    What proofed sufficient for me was the WebView2 control.

    Usage:

    <wpf:WebView2 x:Name="ImageWebView" Grid.Column="0" Grid.Row="0"></wpf:WebView2>
    
    ImageWebView.Source = new Uri(CollectionInformation.Information.NftPreviewFiles[key].FullName);
    

    now no memory impact whatsoever could be found: enter image description here

    unfortunately, WebView2 is a nuget package, albeit from microsoft. it can be found by the name Microsoft.Web.WebView2

    I hope this can help someone