这是我的代码 -
public partial class MainWindow : Window
{
ConcurrentDictionary<int,BitmapSource> Cache = new ConcurrentDictionary<int,BitmapSource>(5, 199);
int width = 720;
int height = 480;
int stride = (width * 3 / 4 ) * 4 + 4;
int currentframe = 0;
public MainWindow()
{
InitializeComponent();
Thread t = new Thread(() =>
{
while (true)
{
for (int i = -9; i < 9; i++)
{
if (!Cache.ContainsKey(currentframe + i))
{
RenderFrameToCache(currentframe + i);
}
}
Thread.Sleep(500);
}
});
t.Start();
}
private object locker = new object();
private void RenderFrameToCache(int frame)
{
byte[] pixels;
//Create byte array
BitmapSource img = BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgr24, null, pixels, stride);
Cache.AddOrUpdate(frame, img, (x,y) => img);
}
private BitmapSource GetBmpSource(int frame)
{
if (Cache.ContainsKey(frame))
{
return Cache[frame];
}
else
{
RenderFrameToCache(frame);
return Cache[frame];
}
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
Cache.Clear();
image.Source = new BitmapImage();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
currentframe++;
image.Source = GetBmpSource(currentframe);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
currentframe--;
image.Source = GetBmpSource(currentframe);
}
}
第二个线程应该用字符填充字典,以便当Window想要显示它们时它们就在手边。 只要按下按钮,就会出现InvalidOperationException。有什么问题?
答案 0 :(得分:2)
使用线程安全ConcurrentDictionary
。
来自MSDN:
所有这些操作[TryAdd,TryUpdate,...]都是原子的,并且是关于的线程安全的 ConcurrentDictionary类上的所有其他操作。 [...]对字典进行修改和写入操作, ConcurrentDictionary使用细粒度锁定来确保 线程安全。 (字典中的读取操作在a中执行 无锁方式。)
答案 1 :(得分:1)
我解决了这个问题。 每次添加新的BitmapSource时我都必须使用BitmapSource.Freeze。 这个链接解释了它 - Multi threading in WPF using C# (with background worker)