2013-12-17 54 views
1

这里是我的代码添加访问词典项目 -被另一个线程

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); 

    } 
} 

第二个线程是为了填补与项目的字典,使他们在手时,窗口要显示他们。 每按一次按钮,都会有一个InvalidOperationException异常。问题是什么?

+2

显示用于尝试读取字典中的值的代码。 – 2013-12-17 00:20:40

+3

您正在进行数据竞赛。当你在另一个线程上阅读时,你不能将元素添加到字典中*。一次从多个线程读取是很好的,但是写入需要独占访问。 – zneak

+0

在additem()中,我在添加项目的代码周围有一个锁定语句,但它不起作用。那是我应该做的吗? – phil

回答

2

使用线程安全ConcurrentDictionary

MSDN

所有这些操作[TryAdd,TryUpdate,...]是原子和是线程安全的ConcurrentDictionary类问候 所有其他操作。 [...]对于字典的修改和写操作, ConcurrentDictionary使用细粒度锁定来确保 线程安全。 (对字典的读操作以 无锁方式执行。)

+0

不幸的是,这没有奏效。如果我不清楚任何事情,请告诉我。 – phil

+0

@phil你可以在你使用ConcurrentDictionary的地方发布代码,但没有工作吗? – kaptan

+0

我已更新它。 – phil