.NET 4.0 アプリケーション (WPF) ではSHGetFileInfo
、ディレクトリ ツリーのシェル アイコンを取得するために使用しています。これにはかなりの時間がかかる場合があるため (つまり、ネットワーク ドライブにアクセスできない場合やフロッピー ドライブの場合)、これをスレッドで実行し、読み込まれたときにアイコンを更新する必要がありました。
呼び出しは基本的に同じで、スレッド内で実行されるだけです。これが機能するにはスレッドが必要であると誰かが言ったのでSTA
、テストには ThreadPool ではなく Thread を使用しましたが、同じ結果が得られました。使用して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
機能させるだけです。これには、アイコンごとにページがハングすることを意味しますが、元の問題 (すべてのアイコンが読み込まれるまでファイル ビューのページが表示されない) が解決されたという利点があります。しかし、少なくともユーザーは何かが起こっていることに気づきます。私たちはまだ問題の実際の解決策を探しています。