In a very simple system a global queue object is fine, but I think it is generally advisable to avoid a global state.
If you are looking to move your logic to C# you may want to take a look at a publish/subscription pattern or an observer pattern.
It is easiest to avoid race conditions or other thread problems if someone owns the queue and controls access to adding or removing items. For this example, I am going to give the queue to the processing thread. The following code example is not tested so there may be problems, but it should give you enough info to get started:
-
public class Processor
-
{
-
private System.Collections.Queue _processQueue = new System.Collections.Queue();
-
public void AddProcessItem(object o)
-
{
-
if (o != null)
-
{
-
lock (_processQueue)
-
{
-
_processQueue.Enqueue(o);
-
}
-
}
-
}
-
-
public void ProcessQueue()
-
{
-
Object processObject = null;
-
while (true)
-
{
-
if (_processQueue.Count > 0)
-
{
-
lock (_processQueue)
-
{
-
processObject = _processQueue.Dequeue();
-
}
-
-
//do processing
-
}
-
}
-
}
-
}
-
-
By moving the queue inside a class you are limiting access to the queue object and therefore limiting potential threading problems.
To add items to the queue, another class is defined that takes a reference to a processor object. This reference is the "subscription" part of the pattern mentioned above. The reference creates a link between the two objects so information can be passed to the processing thread:
-
public class Adder
-
{
-
private Processor _p = null;
-
public Adder(Processor p)
-
{
-
if (p == null)
-
{
-
throw new System.ArgumentNullException();
-
}
-
_p = p;
-
}
-
-
public void DoStuff()
-
{
-
while (true)
-
{
-
//do a bunch of stuff...add item to process queue
-
_p.AddProcessItem(new object());
-
}
-
}
-
}
-
The key here is that one object owns the queue and controls how the queue is accessed. This prevents race conditions and any other threading problems that may come up otherwise. The thread that adds items to the queue gets a reference to the object that owns the queue. All adding to the queue is taken care of by the owning object, again avoiding threading problems.
This model does allow you to add some flexibility to your system if you choose. For example: You can have multiple processing objects and multiple adding objects. The adding objects can be dynamically assigned a queue so you can change who processes items dynamically.
This code example does leave out some fairly large details like how the processing object monitors the queue. It really should not be in a constant loop like shown above. You can do something as simple as schedule a timer to periodically trigger processing of the queue or add more complex logic to trigger the processing method whenever an item is added to the queue. Other experts that have a lot of experience with this pattern may be able to offer better advice on how to overcome that particular challenge.
Hope this helps.