2013-12-17 51 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