2010-06-14 66 views
3

我只是想知道,是Graphics.DrawImage()異步? 我正在努力解決線程安全問題,無法找出問題所在。Graphics.DrawImage是異步的嗎?

如果我使用的GUI線程以下代碼:

protected override void OnPaint(PaintEventArgs e) 
{ 
    lock (_bitmapSyncRoot) 
    { 
     e.Graphics.DrawImage(_bitmap, _xPos, _yPos); 
    } 
} 

而且有下面的代碼在一個單獨的線程:

private void RedrawBitmapThread() 
{ 
    Bitmap newBitmap = new Bitmap(_width, _height); 
    // Draw bitmap // 

    Bitmap oldBitmap = null; 
    lock (_bitmapSyncRoot) 
    { 
     oldBitmap = _bitmap; 
     _bitmap = newBitmap; 
    } 
    if (oldBitmap != null) 
    { 
     oldBitmap.Dispose(); 
    } 
    Invoke(Invalidate); 
} 

莫非是解釋一個accessviolation例外?

該代碼運行在Windows Mobile 6.1設備上,結構緊湊3.5。

編輯:

沒關係,它也發生在該方法在同一個線程得到執行..

+0

這篇文章可能會揭示一些:http://stackoverflow.com/questions/2798812/net-controls-why-arent-all-calls-thread-safe/2798859#2798859 – 2010-06-14 08:21:42

回答

0

嗯,是的DrawImage不異步。該框架不會自動使其異步。此外,大多數.NET中的所有異步操作都以'Begin'開頭,只是fyi。

我不知道在哪裏你的錯誤是從哪裏來的,但你能:

  • 告訴我們哪一行的AccessViolationException是扔?
  • 確保_bitmapSyncRoot被初始化?
+0

我知道'開始'方法,但我很確定不是所有的異步方法都返回一個IAsyncResult? 要回答以下問題: - 這是一個非管理性例外,我的應用程序當場死亡,博士。 watson顯示一個異常對話框。 - 是的,我初始化了SyncRoot對象 – Roy 2010-06-14 09:06:57

+0

感謝您的信息。你能解釋在用戶界面上如何使用各種_<...>位圖嗎?也許這是你的電話給oldBitmap.Dispose(),這是導致問題? 另外,你確定OnPaint是從GUI線程調用的嗎?您可以執行InvokeRequired檢查以確保萬一出現問題。 – Chad 2010-06-14 18:19:55

+0

位圖是listview-like-control中的項目。 (每個項目有1個位圖)我在這裏簡化了代碼,但想法是爲項目設置一個無效隊列,以便單獨的線程可以處理重新繪製項目。關於onpaint:我只調用Invalidate,所以OnPaint由OS/CF處理。 – Roy 2010-06-15 11:14:37

1

是的,是同步的。但是你在這段代碼中做了更大的假設,假設創建任何Graphics對象都是線程安全的。 Afaik它是GDI +的桌面版本。在像WM這樣有限的資源操作系統上這不太可能。沒有任何東西可以鎖定,用於繪畫的東西是在您無法觸摸的代碼中創建的。

+0

確切地說,我在哪裏創建一個圖形對象? – Roy 2010-06-14 09:14:16

+0

在代碼中評論//繪製位圖。 CF在調用OnPaint()之前創建一個。 – 2010-06-14 10:51:05

+0

沒錯,忘了。繪圖都發生在同一個線程內,所以這不應該成爲問題。我想下面不應該拋出任何異常:Graphics.FromImage(...),Graphics.Draw ...(...),Graphics.Dispose()。對? – Roy 2010-06-15 11:22:05