[英]BackgroundWorker and Timer, handling one item at a time
我的應用程序監視用戶可以在其中上傳文件的目錄。 當檢測到新文件時,它將被添加到隊列中。 我有一個計時器,它在隊列中運行,並確定文件是否已完成上傳。 如果有任何完整的文件,它將使用最新文件並開始運行后台任務(使用BackgroundWorker)。
我的問題是我不知道在后台任務運行時如何處理計時器。 例如,如果計時器設置為10秒並且后台工作程序仍在工作,則我希望計時器跳過另一個后台工作程序的執行,直到下一次迭代為止。
另外,每個任務的信息都存儲在Queue(一個ListView控件)中,並將ListViewItem傳遞給后台工作人員。 我很好奇,如果傳遞ListViewItem有任何副作用。
謝謝!
您可以將准備處理的文件存儲在另一個隊列中(例如Queue <string>),然后讓BgWorker連續輪詢該隊列。 您也可能會獲得更好的性能,更少的空閑時間。 您將必須保護隊列(使用Monitor),並讓BgWorker使用Monitor.Wait,當隊列為空時。
要想出個主意,請尋找馬克·格雷夫(Marc Gravell)對這個問題的答案。
在沒有看到您正在談論的代碼的情況下,真的很難回答。 但是,如果必須同步多個異步事件(檢測到文件已下載,將文件添加到隊列,處理隊列),則建議創建一個可以完成所有任務的單個BackgroundWorker。 這樣,您的工作人員就可以輕松地測試每個步驟的狀態。 我會避免創建多個線程並嘗試使其同步,這是非常非常有問題的。
我也不會在UI數據結構(如ListView控件)中存儲任何后台任務信息。 在BackgroundWorker中創建一個回調或事件,該回調或事件將在需要顯示某些內容時提醒UI。
您正在尋找BackgroundWorker.IsBusy屬性嗎?
您可以做的最簡單的事情是在BackgroundWorker中進行所有工作(包括檢查文件夾):檢查是否有事要做,如果可以,請這樣做,否則請使用Sleep(time)或WaitOne(time)掛起線程一段時間。
我認為這里不需要線程安全隊列,因為無論如何文件夾都是異步更新的。 因此,您只需要一個線程, 但是需要一種方法來停止它。 這就是為什么AutoResetEvent.WaitOne(time)優於Sleep(time)的原因-您可以從主線程發出事件信號,以盡早結束后台工作人員。
在您的Timer.Tick處理程序上,檢查BackgroundWorker.IsBusy屬性以確定它是否准備好進行其他工作。 如果沒有,請跳過工作,直到下一個Tick。
您可以創建一個線程隊列,在其中放置工作。 您的后台工作人員會從隊列中取出項目並執行工作。 需要考慮一些事情:
另一種簡便的方法是
我沒有在定時器上跟着你。 如果后台工作人員完成了操作,那么您應該獲得一個事件,並且您將知道它已完成,而無需計時器進行檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.