在 .NET 4.0 应用程序 (WPF) 中,我们SHGetFileInfo
用于获取目录树的外壳图标。由于在某些情况下这需要相当长的时间(即对于无法访问的网络驱动器或软盘驱动器),我们希望在线程中执行此操作,然后在读入图标时更新图标。
调用基本相同,现在只是在一个线程内执行。因为有人说必须要有线程才能STA
工作,所以我们使用Thread而不是ThreadPool进行测试,结果是一样的。使用ThreadPool
也没有用。
SHGetFileInfo
成功(返回 1),但结构中的 hIcon 成员为零。
IntPtr GetIcon(string name)
{
Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES | Shell32.SHGFI_SMALLICON;
Shell32.SHGetFileInfo(
name, System.IO.Directory.Exists(name) ? Shell32.FILE_ATTRIBUTE_DIRECTORY : Shell32.FILE_ATTRIBUTE_NORMAL,
ref shfi,
(uint) System.Runtime.InteropServices.Marshal.SizeOf(shfi),
flags );
return shfi.hIcon;
}
相同的代码在 GUI 线程中运行良好。必须做什么才能使函数从单独的线程中工作,或者在不阻塞 GUI 线程的情况下使其工作?
更新:围绕这个的代码基本上是这样的:
var thread = new System.Threading.Thread(() => {
var result = GetIcon("C:\\");
// ... do something with the result
});
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.Start();
如果只保留线程委托中的行,则它可以正常工作(当然是在 GUI 线程上)。
更新:现在,我们只是调用SHGetFileInfo
它来使其工作。这样做的好处是解决了最初的问题(在加载所有图标之前,不会显示带有文件视图的页面),尽管这意味着页面对于每个图标都挂起。但至少用户现在可以看到正在发生的事情。我们仍在寻找问题的实际解决方案。