我在设计一个媒体播放器,并且我设计了一个电影类。 Movie类有一个MovieInfo成员,它从MediaInfo继承。 MediaInfo有几个属性,代表电影文件的元数据(就是你称之为?),例如文件长度,文件大小,文件路径等。为了提取这些信息,我使用了Shell32。如何优化Shell32方法调用?
问题是Shell32提供的方法非常非常慢。在我的数据库中有1部电影,这不是问题,但有10部电影,它开始变得明显,并有100部电影,大约需要5分钟的时间才能加载该程序,并且在某些情况下,我必须重新初始化运行时的电影,这又会暂停程序的流程。
的的MediaInfo构造函数调用初始化方法:
/// <summary>
/// Initializes all the information variables of the class.
/// </summary>
private void Initialize()
{
Folder mediaFolder = Shell32Processing.GetShellFolder(this.path);
FolderItem media = Shell32Processing.GetShellFolderItem(this.path);
//initialize bit rate value
this.bitrate = mediaFolder.GetDetailsOf(media, 28);
//initialize date accessed value
this.dateAccessed = mediaFolder.GetDetailsOf(media, 5);
//initialize date created value
this.dateCreated = mediaFolder.GetDetailsOf(media, 4);
//initialize date modified value
this.dateModified = mediaFolder.GetDetailsOf(media, 3);
//initialize data rate value
this.dataRate = mediaFolder.GetDetailsOf(media, 279);
//initialize file name value
this.fileName = mediaFolder.GetDetailsOf(media, 155);
//initialize file type value
this.fileType = mediaFolder.GetDetailsOf(media, 181);
//initialize folder value
this.folder = mediaFolder.GetDetailsOf(media, 177);
//initialize folder name value
this.folderName = mediaFolder.GetDetailsOf(media, 175);
//initialize folder path value
this.folderPath = mediaFolder.GetDetailsOf(media, 176);
//initialize frame height value
this.frameHeight = mediaFolder.GetDetailsOf(media, 280);
//initialize frame rate value
this.frameRate = mediaFolder.GetDetailsOf(media, 281);
//initialize frame width value
this.frameWidth = mediaFolder.GetDetailsOf(media, 282);
//initialize length value
this.length = mediaFolder.GetDetailsOf(media, 27);
//initialize title value
this.title = FileProcessing.GetFileTitle(this.path);
//initialize total bitrate value
this.totalBitrate = mediaFolder.GetDetailsOf(media, 283);
//initialize size value
this.size = mediaFolder.GetDetailsOf(media, 1);
}
这里是Shell32Processing.GetShellFolder方法:
/// <summary>
/// Gets a Shell32 Folder, initialized to the directory of the file path.
/// </summary>
/// <param name="path">A string representing the file/folder path</param>
/// <returns>The Shell32 Folder.</returns>
public static Folder GetShellFolder(string path)
{
//extract the folder subpath from the file path
//i.e extract "C:\Example" from "C:\Example\example.avi"
string directoryPath = new FileInfo(path).Directory.ToString();
return new Shell().NameSpace(directoryPath);
}
而且Shell32Processing.GetShellFolderItem方法:
/// <summary>
/// Gets a Shell32 FolderItem, initialized to the item specified in the file path.
/// </summary>
/// <param name="path">A string representing the file path.</param>
/// <returns>The Shell32 FolderItem.</returns>
/// <exception cref="System.ArgumentException">Thrown when the path parameter does not lead to a file.</exception>
public static FolderItem GetShellFolderItem(string path)
{
if (!FileProcessing.IsFile(path))
{
throw new ArgumentException("Path did not lead to a file", path);
}
int index = -1;
//get the index of the path item
FileInfo info = new FileInfo(path);
DirectoryInfo directoryInfo = info.Directory;
for (int i = 0; i < directoryInfo.GetFileSystemInfos().Count(); i++)
{
if (directoryInfo.GetFileSystemInfos().ElementAt(i).Name == info.Name) //we've found the item in the folder
{
index = i;
break;
}
}
return GetShellFolder(path).Items().Item(index);
}
每次调用GetDetailsOf(这是Shell32提供的代码)需要一个不可思议的处理时间 - 我使用ANTS分析器来找到这个问题,因为起初我无法确定是什么让我的程序变慢。
所以问题是:我如何优化Shell32方法,如果我不能,是否有替代方案?
谢谢!这并没有完全解决问题,但仍然有明显的延迟,但现在它变短了:)。 – Daniel
@Daniel另外,这些是COM对象,所以不要忘记释放它们。我已经更新了上面的Initialize,以显示最正确的方式来做到这一点。 'Marshal'可以在'System.Runtime.InteropServices'中找到(mscorlib) – Tergiver
哦,我不知道我需要这么做。谢谢 :) – Daniel