【发布时间】:2017-04-26 08:28:54
【问题描述】:
我已经构建了一个可以从 USB 驱动器读取视频文件并使用物理按钮在它们之间切换的应用程序。该应用程序在一段时间内运行良好,但在一段时间后,设备(DragonBoard 410c,最新的 Windows Insider Preview Build 15051)由于应用程序消耗了所有内存而崩溃。
查看设备门户中的进程,我可以看到每次切换视频文件时“工作集”内存都会跳跃,而“私有工作集”大致保持不变(大约 30MB)。
这是我加载视频文件的方式:
C#
private IReadOnlyList<StorageFile> _videofiles
// list all available video files
public void Init(){
var queryOptions = new QueryOptions();
queryOptions.FolderDepth = depth;
foreach (var fileType in fileTypes)
{
queryOptions.FileTypeFilter.Add(fileType);
}
var query = KnownFolders.RemovableDevices.CreateFileQueryWithOptions(queryOptions);
_videofiles = await query.GetFilesAsync();
}
private async void SelectVideo(int videoId)
{
StorageFile videofile = _videofiles.Where(x => x.DisplayName == videoId.ToString()).FirstOrDefault();
if (videofile != null)
{
Debug.WriteLine($"Video {videofile.DisplayName} was selected");
var stream = await videofile.OpenAsync(FileAccessMode.Read);
VideoPlayer.SetSource(stream, videofile.FileType);
}
}
// since the button interrupt is not on the UI thread, SelectVideo() is called like this
private async void SelectVideoMarshalled(int videoId)
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
SelectVideo(videoId);
});
}
XAML
<ContentControl x:Name="VideoPlayer" Content="{x:Bind ViewModel.VideoPlayer, Mode=OneWay}"/>
我曾尝试在多个地方手动运行 GC.Collect(),但还没有成功。有什么想法吗?
【问题讨论】:
-
只是一个快速的想法,但每个流都是一次性的,因此您应该在将之前设置为
VideoPlayer源的流设置为SelectVideo中的新流实例后将其处理掉方法, -
调用stream.Dispose();在 VideoPlayer.SetSource() 之后(这是发生内存峰值的地方)没有帮助。
-
即使导航到不同的页面也无助于释放内存
-
是的,它没有帮助,因为您正在处理流的当前实例 - 您希望在播放器中的那个实例。您应该处置前一个实例 - 当您在其上调用
SetSource方法时,该实例将从VideoPlayer中删除。
标签: c# memory-leaks uwp windowsiot windows-iot-core-10