相关疑难解决方法(0)

在线程中调用SHGetFileInfo以避免UI冻结

在.NET 4.0应用程序(WPF)中,我们使用SHGetFileInfo获取目录树的shell图标.由于这在某些情况下需要相当长的时间(即对于无法访问的网络驱动器或软盘驱动器),我们希望在一个线程中执行此操作,然后在读入时更新图标.

调用基本相同,现在只是在一个线程中执行.因为有人说线程必须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;
}
Run Code Online (Sandbox Code Playgroud)

完全相同的代码可以从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();
Run Code Online (Sandbox Code Playgroud)

如果只留下线程委托中的行,它可以正常工作(当然,在GUI线程上).


更新:目前,我们只是调用SHGetFileInfo它来使其工作.这样做的好处是,原始问题(在加载所有图标之前未显示文件视图的页面)已经解决,但这意味着页面会挂起每个图标.但至少用户现在看到了一些事情正在发生.我们仍在寻找问题的实际解决方案.

windows multithreading shell32 .net-4.0

6
推荐指数
2
解决办法
2009
查看次数

标签 统计

.net-4.0 ×1

multithreading ×1

shell32 ×1

windows ×1