2009-06-18 36 views
4

我有兩個列表框,一個是主人,另一個是孩子。當主索引上的索引發生變化時,子列表框將被正確填充與主索引有關的記錄。當一位主人花費很長時間獲取所有記錄,並且在完成獲取記錄之前,用戶點擊另一位需要較少時間填寫的主人,我的問題即將到來。發生的是,最終,即使用戶不在該主人身上,花費較長時間的主人也會填充子列表框。取消winforms中的工作線程

我一直在使用BackgroundWorker線程來做填充。

bw_LoadAll.DoWork += new DoWorkEventHandler(bg_LoadAllWork); 
bw_LoadAll.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_LoadAllWorkCompleted); 
bw_LoadAll.WorkerSupportsCancellation = true; 

我訂閱了SelectedIndexChanged事件的主人和我設置取消等於真:

bw_LoadAll.CancelAsync(); 

這裏是在DoWork的方法的代碼:

List<object> s = Repository.Instance().LoadAll(); 
if (!bw_LoadAll.CancellationPending) { 
    e.Result = s; 
} else { 
    e.Cancel = true; 
} 

但對於某種原因,工作人員完成的代碼不斷被調用。這裏是工作人員完成代碼:

if (!e.Cancelled) { 
    ddl.DataSource = e.Result; 
    ddl.DisplayMember = "QuickName"; 
    ddl.ValueMember = "ID"; 
} 

有沒有別的東西,我必須做的,從返回取消這個線程?

回答

5

你的方法,bg_LoadAllWork,應該被定義爲:

void bg_LoadAllWork(object sender, DoWorkEventArgs e) 
{ 
    // Do your work here... 
} 

內bg_LoadAllWork的,你需要檢查e.CancellationPending,如果這是真的,設置e.Cancel = true;

最後這部分是非常重要的 - 如果你從未設置e.Cancel,那麼你的「e.Cancelled」將永遠不會等於true。對CancelAsync的調用實際上並不會取消任何內容 - 更像是「請求後臺工作取消」 - 您必須將邏輯放置到導致取消的位置。

+0

CancellationPending未公開在DoWorkEventArgs上,而不是在BackgroundWorker上顯示,在此示例中該參數爲參數。 – Sherlock 2010-10-02 05:47:24

0

從您的do_work函數中的CodeProject您需要檢查工作線程上的CancellationPending,然後將DoWorkEventArgs.Cancel變量設置爲true。

+0

如果我在點擊主項目之間花費時間,那麼這個方法就行得通,但如果我點擊一下,然後點擊另一個點擊,它似乎不會及時設置。我將更新代碼以顯示我在工作方法中所做的工作。 – Josh 2009-06-18 16:58:31

0

它是因爲我已經使用了BackgroundWorker的一段時間,但如果我沒有記錯,當你調用bw_LoadAll.CancelAsync,還有你LoadAllWork方法沒有實際的流產,除非LoadAllWork檢查bw_LoadAll.CancelationPending

通過http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx證實:「CancelAsync提交終止掛起的後臺操作的請求,並將CancellationPending屬性爲true

當你調用CancelAsync,您的輔助方法有機會停止其執行和。退出。工作人員代碼應定期檢查CancellationPending屬性,看它是否已設置爲true。「

所以,在你SelectedIndexChanged事件處理程序中,當你調用bw_LoadAll.CancelAsync(),它的設置bw_LoadAll.CancelationPending爲真,但它實際上沒有中止LoadAllWork方法。慢加載程序仍將完成。