2013-06-26 29 views
0

我有一個生成事件的用戶界面。所以我有事件例如「ButtonPressed」與參數。 關於事件我想引發耗時的函數「GenerateTableData」。我也不想阻塞接口,所以這個函數應該在後臺線程上。 在此之後,我可以將調用傳遞迴主線程並填充列。
但是,如果用戶在按鈕上按兩次,我不想創建兩個線程。相反,我想打斷這個私密的人,或者等到它完成並立即開始另一個(單獨的按鈕用單獨的數據填充表格,我們只需要顯示最後一個按下的結果)。c上的單線程隊列#

我被這個選項卡住了。所有對我來說都很有用的工作是在每個事件上投入背景工作,但我無法阻止它執行兩次或更多次,也無法排隊進一步事件。

請給我一個解決這個任務的例子,我認爲它應該很常見。

下面是一些僞代碼:

void Button1Pressed(args) 
{ 
DoWork(1); 
} 
void Button2Pressed(args) 
{ 
DoWork(2); 
} 

void DoWork(int i) 
{ 
BackGroundWorker bg=new BackGroundWorker(); 
bg.DoWork+= (object sender, DoWorkEventArgs e) => {e.result=GenerateTable(i)}; 
bg.RunWorkerCompleted+= (object sender, RunWorkerCompletedEventArgs e) =>{InvokeOnMainThread(()=>{PopulateColumns(e.result)})}; 
bg.RunWorkerAsync(); 
} 
void PopulateColumns(data) 
{ 
myTable.PopulateWithData(data); 
} 

回答

0

做到這一點的典型方式是:

  • 爲每個事件類型,應序列,有一個隊列
  • 引發事件正排隊事件和踢隊列(見下文)
  • 將工人包裝在一個方法中,在完成任務後
    • 重置了一個 「工人正在運行」 標誌(無需鎖定)
    • 踢隊列再次

通過 「踢隊列」 我的意思是

  • 檢查「工人正在運行」標誌,如果已設置,則什麼也不做(結束工人將重新踢)
  • 嘗試從鎖定隊列中退出,如果是空的,解鎖,什麼也不做
  • 所以我們有工作要做:以前解鎖隊列中,將「工人正在運行」國旗
+0

什麼是更好的方式來組織隊列?列表還是smth? –

+0

無論最合適 - 我通常使用System.Collections.Generic.Queue (http://msdn.microsoft.com/en-us/library/7977ey2c.aspx) –

+0

謝謝。一整天都在嘗試創建解決方案,並一直努力重現錯誤。問題是在內部方法中讀取SQLite不是線程安全的。最後,我明白了,現在沒問題。 –