If I understand you, you want the Producer thread to wait while the number of UI windows is at a certain threshold. I would use a Semaphore shared by the producer and consumer and initialized to the max window count to accomplish this behavior.
If I understand you, you want the Producer thread to wait while the number of UI windows is at a certain threshold. I would use a Semaphore shared by the producer and consumer and initialized to the max window count to accomplish this behavior. Const int MaxWindowCount = 5; Sempahore semaphore = new Semaphore(0, MaxWindowCount ); Before each enqueue, you call semaphore.WaitOne(); And once each task is accomplished and its window is closed, call semaphore.Release(); Once MaxWindowCount items have been enqueued, your producer will wait on its next call to WaitOne() and will wait until Release() is called.
Hmm, this may not accomplish what you want, since it is limiting the number of items in the queue to MaxWindowCount , not necessarily the number of open windows. It assumes that each item in the enqueued has an open window, which may not be true in your case. If that's an invalid assumption, you could have a thread responsible for pulling items from the queue.
This thread would be responsible for calling WaitOne() while handing items off to the UIController. The UIController is still responsible for calling Release(). In effect, you would have two producer-consumer queues.
One unbounded queue for tasks and one bounded queue for windows. --Added May 21, 2010 -- Another option might be to have the call to CreateWindow take a callback parameter, telling the controller the number of open windows. Using the following delegate as a parameter to CreateWindow, you could keep the count of open windows in the Worker and act accordingly when the max is reached.
Public delegate void CreateWindowCallback( int numOpenWindows ); You'd may keep a count of open windows in your worker and you'd need to let worker know the max window count. Alternatively, you could keep a CanOpenNewWindows boolean in your Controller class. Before a call to _UIthread.
BeginInvoke the worker could check the current window count (or the CanOpenNewWindows property) and if it shouldn't open a new window call WaitOne(). You would still need the something to know when windows are closed, in order to Release/Signal the worker to continue. In the case where window creation fails, or the controller doesn't need to display a window you can let the worker know that the open window count hasn't increased.
This does assume that _controller knows whether or not a window was created. -- Another thought -- It may be possible to keep all of the window creation logic in your UIController. UIController would need to know the UIThread and modify the CreateWindow call to accept only a task.
A call to CreateWindow(task) would call BeginInvoke if there are less than max windows open. Otherwise, it calls WaitOne() and waits for one of the windows to signal that they've closed. We could use a semaphore here, calling WaitOne() after each successful window creation.
Each window would be responsible for calling Release() when it closes. This way, when the worker calls CreateWindow directly, it will block when max window count is reached and it never has to know the max window count or much else about the UI.
Thanks for the input. The issue is that the consumer may be unsuccessful in opening the window, or, decide not to open one. The last suggestion sounds good.
I'm not clear exactly how this would work but I will have a play around. – Mike May 20 '10 at 21:58 Whilst I work out the bounded and unbounded solution I have had some success with just (re) enqueing the unwanted message back on the queue. It's a tad messy as I am having to pass around a fair number of classes in the constructor so that the UIcontroller can see my queue.
What ever I do, I need to refactor. – Mike May 20 '10 at 22:40 My (surprisingly straight-forward, as it happens) solution is to (optimistically) open up to max no of windows by calling the UI controller. Then I WaitOne.
The UIcontroller re-activates the worker thread with a count reset to the no of windows available: whenever one or more windows are closed... The only issue is that if one or more windows fails to open, I may only open 1 window rather than the maximum allowed. If all fail to open, I may block 'permanently'. I can deal with this in error handling.
– Mike May 21 '10 at 2:31 I realize I'm spewing ideas out. The more I think about it, the more ways there seems to be to skin this cat. – Ed Gonzalez May 21 '10 at 12:04 Ed - many thanks.In the end I did precisely what you suggested- use a delegate.
I hadn't realised though you could put the delegate as a parameter - I need to re-read the use of delegates! – Mike May 28 '10 at 6:11.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.