我有一個靜態類,它包含文件擴展名和BitMapSource對象的字典。該類包含一個函數,如果FileInfo對象返回關聯的BitMapSource對象,如果該對象不在字典中,它將得到它並在返回之前將其放入字典中。
從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對象。我改變了我的字典,並改變了添加到TryAdd,但它似乎並沒有解決問題。 – JtM
BitmapSource是一個DependencyObject,這意味着它只能由創建它的線程使用。 –