2010-07-13 51 views
2

我有一個FileSystemWatcher設置爲拾取一個圖片,將被放置在一個特定的目錄。我處理它的方式是在停靠在面板內的代碼中添加一個PictureBox。我跑了它,它爆炸了,我意識到我沒有正確處理與主線程上的控件的交互。下面是代碼:好奇WinForm控制線程安全後,在一個單獨的線程上添加控件

 PictureBox pb = new PictureBox(); 
     pnlCapturePicture.Controls.Add(pb); 
     pb.Dock = DockStyle.Fill; 
     pb.ImageLocation = photopath; 

現在我明白瞭如何使[線程安全的調用到Windows窗體控件] [1],但我很好奇,如果我只是使面板中的添加線程安全的是我真的完成什麼?

說,如果我這樣做:

 PictureBox pb = new PictureBox(); 
     AddControlThreadSafe(pb); 
     pb.Dock = DockStyle.Fill; 
     pb.ImageLocation = photopath; 

與PictureBox控件交互它被添加到面板後真的是線程安全的?

回答

2

不,它不起作用。 全部 GUI代碼必須在適當的用戶界面線程上完成。線程上下文不會一直被檢查,所以可以編寫類似於現在可以工作但未來的.NET框架更新失敗的東西。

在你的情況下,FileSystemWatcher瞭解ISynchronizeInvoke模式,所以只需將其SynchronizingObject屬性設置爲它的工作形式。請注意,如果您使用設計器在表單上放置了FileSystemWatcher,則會自動設置此屬性。

+0

謝謝斯蒂芬,你回答了我甚至沒有問,但應該有的問題! – Flory 2010-07-14 15:33:43

2

沒有將無法工作。那麼,至少它不會一直工作。它可能會工作一段時間,但最終它會失敗和不可思議地失敗。一般的規則是你不能對任何其他線程上的FormControl做任何事情,除此之外的其他線程。換句話說,他們有線程親和力。你真正需要做的是讓主UI線程通過編組消息來創建和修改PictureBox。這可以通過利用ISynchronizeInvoke方法來完成。所有的窗體和控件都實現這個接口。

public void ThreadMethod() 
{ 
    pnlCapturePicture.Invoke((Action)(() => 
    { 
    PictureBox pb = new PictureBox(); 
    pnlCapturePicture.Controls.Add(pb); 
    pb.Dock = DockStyle.Fill; 
    pb.ImageLocation = photopath; 
    })); 
}