-1

In my CheckQueue() method, what I want to do is constantly read from the queue (by calling the AppQ.Connect(Time)) and TryDequeue each item off of it. After some elapsed time (maybe a minute or so), I want to go back to the queue - connect again, check if it has some elements (AppQ.Count), read them (by TryDequeue()) and do this process indefinitely.

This is for an application which will be made a Windows Service (currently a Windows Forms Application for testing purposes) that will run all day everyday and alert us the developers when there is some downtime in any application running on some machine. I know I will have to use a While-Loop but I am unsure whether to use a Timer based event or a Stopwatch along with it.

More context: I also have a feeling that I should consider making use of a do-while loop as opposed to a while seeing as the former performs some action (load messages by calling AppQ.Connect(time)) then check the exit condition (if AppQ.Count <= 0) whereas a while does the opposite.

Should I use a BlockingCollection<T> considering it is thread-safe?

Any suggestions?

 public class APPInfo
 {
        public String Machine { get; set; }
        public String IP { get; set; }
        public String Port { get; set; }
        public String App { get; set; }
        public ClientApplicationState Status { get; set; }
        public String Message { get; set; }
        public String TimeStamp { get; set; }
        public String CPUUse { get; set; }
        public String MemoryUse { get; set; }
        public String TotalCPUUse { get; set; }
        public String TotalMemoryUse { get; set; }
 }

public static ConcurrentQueue<APPInfo> AppQ = new ConcurrentQueue<APPInfo>();

 public static void Connect(Int16 Time)
 {    
       AppQ.Enqueue(new APPInfo { Machine = "One", IP = "127.0.0.1", Port = "23000", App = "TestServer1", Status = ClientApplicationState.OK, TimeStamp = DateTime.Now.ToString(), CPUUse = "80.0", MemoryUse = "81.0", TotalCPUUse = "86.0", TotalMemoryUse = "87.0" });

       AppQ.Enqueue(new APPInfo { Machine = "One", IP = "127.0.0.1", Port = "23001", App = "TestServer2", Status = ClientApplicationState.ERROR, TimeStamp = DateTime.Now.ToString(), CPUUse = "82.0", MemoryUse = "83.0", TotalCPUUse = "88.0", TotalMemoryUse = "89.0" });

       AppQ.Enqueue(new APPInfo { Machine = "Two", IP = "127.0.0.2", Port = "23002", App = "TestServer3", Status = ClientApplicationState.WARNING, TimeStamp = DateTime.Now.ToString(), CPUUse = "84.0", MemoryUse = "85.0", TotalCPUUse = "90.0", TotalMemoryUse = "91.0" });        
 }

 private void CheckQueue()
 {
     AppIP.Connect(50);
     APPInfo first = new APPInfo();         

     if (AppIP.AppQ.Count > 0)
     {
         AppIP.AppQ.TryDequeue(out first);

        MessageBox.Show(first.App, first.IP, first.Port, first.Status.ToString(), first.Message, first.TimeStamp, first.CPUUse, first.MemoryUse, first.Machine, first.TotalCPUUse, first.TotalMemoryUse + "\n");
     }
     else
     {
          MessageBox.Show("There is nothing in the queue to process.", "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
     }
 }

miscellaneous: Can people post comments on where I may have gone wrong instead of just down voting a post and not giving reason

Harold_Finch
  • 682
  • 2
  • 12
  • 33
  • 1
    You are probably better off using something like Rx or at least, as you already mentioned, a blocking collection. – Num Lock Jul 13 '17 at 09:06
  • @NumLock I've been searching relentlessly but I can't find any examples related to Rx. Can you point me in the right direction? I have never worked with it before. – Harold_Finch Jul 13 '17 at 10:11
  • 1
    He is probably better off creating a wrapper around the ConcurrentQueue, adding Enqueue /Dequeue methods. Then either trigger an event when something is enqueued to do the processing, or directly calling a routine that loops until the queue is empty. – David C Fuchs Oct 04 '19 at 21:46

1 Answers1

1

In order to check queue once in a while you need to setup a timer:

 CheckTimer = new System.Threading.Timer(CheckQueue, null, TimeSpan.FromMilliseconds(1000), TimeSpan.FromMilliseconds(1000));

You should create the timer when you are initializing your service.

In your CheckQueue method you will need a loop to handle all the data in the queue.

private void CheckQueue(object dummy)
{
    // The dummy is null, its there because it is a Timer event.
    AppIP.Connect(50);

    AppInfo appInfo;
    while(AppQ.TryDequeue(out appInfo))
    {
        // Process the appInfo
    }
}

Note that the timer from System.Threading will run in different threads and the processing of the next event will happen even if the current event is still running!

Casperah
  • 4,504
  • 1
  • 19
  • 13