嗨,我有一個生產者 - 消費者模式。 WPF UI對於長時間運行的工作線程來說是一種輔助工具,它正在偵聽數據包並使任務進入隊列。在實踐中,所有消息都被出隊,然後UI消費者進行處理。WPF工作者線程需要通過消費者通知暫停
我遇到的問題是我有一個UIcontroller類負責所有的WPF GUI組件。它打開一個新窗口,顯示每個出隊任務並保存一個線程安全的引用窗口集合。
我通過Despatcher.BeginInvoke發出信號。那裏沒有驚喜。
我遇到的問題是,如果UIController類成功打開一個配置數量的窗口,我想暫停/逐字停止我的工作線程。打開的窗口數量有限制。一旦打開的窗口數量減少回到範圍內,我將恢復對隊列的處理。我試着把這個窗口集合保存在這個類中,並通過調用將它傳遞給UI,在這裏通過引用更新它,但Begin Invoke是異步的,並且計數在工作線程的循環中沒有及時更新。
我可以在UIcontroller類中測試打開的窗口的否,忽略甚至重新從那裏執行任務 - 基本上不採取任何行動。但我想要一個更清潔的解決方案。
我可以做一些乾淨的回調嗎?
public void Work()
{
while (true)
{
Log.Instance.Info("****In worker THREAD " + _worker.Name);
while (_controller.IncomingMessages.Count > 0 && [--test for no of windows open on GU thread somehow - I did try holding a reference to the collection in this class--])
{
try
{
Log.Instance.Info("****In Notification worker THREAD and messages to process " + _worker.Name);
Messages.AlertMessage task = null;
lock (_locker)
{
if (_controller.IncomingMessages.Count > 0 && ToasterPopUps.Count < 5)
{
task = _controller.IncomingMessages.Dequeue();
if (task == null)
{
return;
}
}
if (task != null)
{
Log.Instance.Info("Dequeing: " + task + " " + task.ID + " from Notification thread");
_UIthread.BeginInvoke(DispatcherPriority.Background, new JoinUIThread(DespatchUIThread), task, _UIthread);
}
}
}
catch (Exception err)
{
Log.Instance.Critical(string.Format("Unexpected Error in PollPopUp Thread Queue {0} ", err));
}
}
Log.Instance.Info("No more Notification tasks - wait for a signal");
_wh.WaitOne();
}
}
public void DespatchUIThread(Messages.AlertMessage task, System.Windows.Threading.Dispatcher dispatcherThread)
{
try
{
_controller.CreateWindow(task, dispatcherThread);
}
catch (Exception err)
{
Log.Instance.Critical("Critical error " + err);
}
}
感謝您的意見。問題在於消費者可能無法打開窗戶,或者決定不打開窗戶。 最後的建議聽起來不錯。我不清楚這究竟會如何工作,但我會玩一玩。 – Mike 2010-05-20 21:58:56
雖然我研究了有界和無界的解決方案,但我只是在隊列中將(不希望的)消息重新排入隊列,取得了一些成功。這是一個混亂,因爲我不得不在構造函數中傳遞相當數量的類,以便UI控制器可以看到我的隊列。我做了什麼,我需要重構。 – Mike 2010-05-20 22:40:40
我的(令人驚訝的直截了當,正如它發生的那樣)解決方案是通過調用UI控制器來(樂觀地)打開最多的窗口。然後我等一下。 UI控制器重新激活工作線程,並將計數重置爲可用窗口的數量:每當關閉一個或多個窗口時... 唯一的問題是,如果一個或多個窗口無法打開,我只能打開1窗口而不是允許的最大值。如果一切都打不開,我可能會永久封鎖。我可以在錯誤處理中處理這個問題。 – Mike 2010-05-21 02:31:27