Hi I have a producer - consumer pattern. The WPF UI is sort of ancilliary to a long-running worker thread which is listening to packets and enqueing tasks. In practise all the messages are dequeued and then the UI consumer processes.
The issue I have is that I have a UIcontroller class which is responsible for all WPF GUI components. It opens a new window displaying each dequeued task and holds a thread-safe collection of referenced windows.
I signal by Despatcher.BeginInvoke. No surprises there.
The issue I have is that I want to suspend/literally halt my worker thread if the UIController class successfully opens a cconfigured number of windows. There is a limit on the number of windows open. Once the number of windows open reduces back within bounds I resume the processing of the queue. I tried holding my window collection here in this class and passing it to the UI via the call where it is updated by reference but the Begin Invoke is Asynchronous and the count is not updated in time in the loop of the worker thread.
I could test the no of windows open in the UIcontroller class, ignore and even requeue the task from there - essentially taking no action. But I'd like a cleaner solution.
Can I do some sort of clean callback?
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);
}
}