Skip to content

Instantly share code, notes, and snippets.

@Immerseit
Created June 30, 2011 21:18
Show Gist options
  • Save Immerseit/1057263 to your computer and use it in GitHub Desktop.
Save Immerseit/1057263 to your computer and use it in GitHub Desktop.
Not complete ServiceQueue problem that need some help,
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// My problem description. You are welcome to comment/fork your own tried/functional versions of this.
// Appearently I have successed the queue on all needed situations. Except a trivial one, the ervice aren't really dequeue.
// The two methods below is two services that are ranned simultaneous within same application (a Windows Service).
//
// 1# As I can see, the line 'if (queue.TryDequeue(..))' never get looped/waked-up..
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// The object that will Enqueue, put object into Queue (can be put into a console application)
//
public void Start()
{
isListening = true;
Thread listener = new Thread(() =>
{
while (isListening)
{
receivedStream = udpClient.Receive(ref endPoint);
try
{
EchoToSender(receivedStream, endPoint);
request = new Datagram.Request();
request = Deserialize(receivedStream);
queue.Enqueue(request);
}
catch (SocketException ex)
{
WriteToFile(ex.ToString());
break;
}
catch (Exception ex)
{
WriteToFile(ex.ToString());
break;
}
}
});
listener.IsBackground = true;
listener.Start();
}
//
// Dequeue service. This method will take "next object in queue" (can be put into a console application)
//
public void Start()
{
Thread listener = new Thread(() =>
{
new Datagram.Request packet;
while (true)
if (queue.TryDequeue(out packet, new Random().Next(20)))
packet = (Datagram.Request)queue.Dequeue();
});
listener.IsBackground = true;
listener.Start();
}
//
//
//
// This is the Queue service itself. ServiceQueue.cs
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ServiceName
{
public class ServiceQueue<T> where T : class
{
private bool isClosing;
private readonly Queue<T> queue = new Queue<T>();
private readonly int maxSize;
public bool Enqueue(T item)
{
lock (queue)
{
if (isClosing || null == item)
return false;
while (queue.Count >= maxSize)
Monitor.Wait(queue);
queue.Enqueue(item);
if (queue.Count > 0)
Monitor.PulseAll(queue);
return true;
}
}
public T Dequeue()
{
T item;
lock (queue)
{
while (queue.Count == 0)
Monitor.Wait(queue);
item = queue.Dequeue();
if (queue.Count > 0)
Monitor.PulseAll(queue);
return item;
}
}
public bool TryDequeue(out T value)
{
lock (queue)
{
while (queue.Count == 0)
{
if (isClosing)// !Monitor.Wait(queue, timeout))
{
value = default(T);
return false;
}
Monitor.Wait(queue);
}
value = queue.Dequeue();
if (queue.Count == maxSize - 1)
{
//wake up blocking enqueue
Monitor.PulseAll(queue);
}
return true;
}
}
public void Close()
{
lock (queue)
{
if (!isClosing)
{
isClosing= true;
queue.Clear();
}
}
}
public void Clear()
{
lock (queue)
{
queue.Clear();
Monitor.Pulse(queue);
}
}
public int Count
{
get
{
lock (queue)
{
return queue.Count;
}
}
}
public ServiceQueue()
{
this.maxSize = 500;
lock (queue)
{
isClosing = false;
Monitor.PulseAll(queue);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment