访问由另一个线程添加的字典项

时间:2013-12-17 00:18:54

标签: c# wpf multithreading

这是我的代码 -

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。有什么问题?

2 个答案:

答案 0 :(得分:2)

使用线程安全ConcurrentDictionary

来自MSDN

  

所有这些操作[TryAdd,TryUpdate,...]都是原子的,并且是关于的线程安全的   ConcurrentDictionary类上的所有其他操作。   [...]对字典进行修改和写入操作,   ConcurrentDictionary使用细粒度锁定来确保   线程安全。 (字典中的读取操作在a中执行   无锁方式。)

答案 1 :(得分:1)

我解决了这个问题。 每次添加新的BitmapSource时我都必须使用BitmapSource.Freeze。 这个链接解释了它 - Multi threading in WPF using C# (with background worker)