我在設計一個媒體播放器,並且我設計了一個電影類。 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