ファイル拡張子とBitMapSourceオブジェクトの辞書を含む静的クラスがあります。そのクラスには、関連するBitMapSourceオブジェクトがFileInfoオブジェクトで返され、まだ辞書にない場合は取得して辞書に戻してから返す関数が含まれています。
これはGUIスレッドから実行するとうまく動作します。しかし、バックグラウンドスレッドに入れようとすると、何も戻ってこない。バックグラウンドスレッドからこれを実行できないようにすべき理由はありますか?静的クラスを使用した非同期関数
静的クラス
namespace Test.Classes
{
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
public static class IconMap
{
private static Dictionary<string, BitmapSource> iconDictionary = new Dictionary<string, BitmapSource>();
public static BitmapSource GetFileIcon(FileInfo fileInfo)
{
if (iconDictionary.ContainsKey(fileInfo.Extension))
{
return iconDictionary[fileInfo.Extension];
}
else
{
lock (iconDictionary)
{
Icon icon = Icon.ExtractAssociatedIcon(fileInfo.FullName);
BitmapSource bitMapSource = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, new Int32Rect(0, 0, icon.Width, icon.Height), BitmapSizeOptions.FromEmptyOptions());
iconDictionary.Add(fileInfo.Extension, bitMapSource);
return bitMapSource;
}
}
}
}
}
Control.cs
namespace Test.Controls
{
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Microsoft.Office.Interop.Outlook;
public partial class AttachedFileInfo : UserControl
{
private FileInfo file;
public AttachedFileInfo(FileInfo fileInfo)
{
this.InitializeComponent();
this.file = fileInfo;
this.FileLink.NavigateUri = new Uri(fileInfo.FullName);
this.FileName.Text = fileInfo.Name;
this.LoadFileIcon(fileInfo);
}
private async void LoadFileIcon(FileInfo fileInfo)
{
Task<BitmapSource> getFileIconTask = Task<BitmapSource>.Factory.StartNew(() =>
{
// If I change this to BitmapSource icon = null; it works as expected.
BitmapSource icon = Classes.IconMap.GetFileIcon(fileInfo);
return icon;
});
await getFileIconTask;
this.FileIcon.Source = Classes.IconMap.GetFileIcon(fileInfo);
// getFileIconTask.Result;
}
private void FileLink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(this.file.FullName);
}
}
}
辞書から同時に読み書きすることは安全ではありません。 'ConcurrentDictionary'を使うか、' ReaderWriterLockSlim'でアクセスをラップして、書き込み中に並行読者をブロックしてください。 –
ありがとうございます。私はConcurrentDictionaryオブジェクトを認識していませんでした。私は辞書を変更してAddをTryAddに変更しましたが、問題を解決できないようです。 – JtM
BitmapSourceはDependencyObjectです。つまり、BitmapSourceは、それを作成したスレッドによってのみ使用できます。 –