Avatar billede sph1nx Nybegynder
07. oktober 2008 - 11:08 Der er 9 kommentarer og
1 løsning

2 tråde om samme Queue

Skal lave et lille app til at sende SMS over serial porten, i den forbindelse vil jeg gerne have en Queue at skrive beskederne ind i før de bliver sendt, så der ikke er noget der går tabt..

jeg er kommet frem til nedestående, det er bare noget test for at se om man kunne gøre det på en queue. Men kan man lave det "pænere"

static Queue _smsQueue = null;
static void Main(string[] args)
{
  Thread fill = new Thread(new ThreadStart(fillQueue));
  Thread process = new Thread(new ThreadStart(processQueue));
  fill.Start();
  process.Start();
}

static void processQueue()
{
  while (true)
  {
      if (_smsQueue.Count > 0)
      {
        Console.WriteLine(_smsQueue.Dequeue());
      }
  }
}

static void fillQueue()
{
  if (_smsQueue == null)
  {
      _smsQueue = new Queue();
  }

  for (int i = 0; i < 10000; i++)
  {
      _smsQueue.Enqueue(i);
  }
  }
}
Avatar billede kalp Novice
07. oktober 2008 - 14:51 #1
Hvis det er MessageQueue vi taler om bør du læse beskeder fra den via. Eventet RecieveCompleted.

F.eks sådan her.

logViewQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
logViewQueue.BeginReceive();

private void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult) {
MessageQueue queue = (MessageQueue)source;
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(XmlDocument) });
System.Messaging.Message message = new System.Messaging.Message();
message = queue.EndReceive(asyncResult.AsyncResult);
}
Avatar billede kalp Novice
07. oktober 2008 - 14:51 #2
hvis ikke dine beskeder er overført i XML format skal du ændre på linjen:
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(XmlDocument) });

eller sende dine beskeder i XML format, som er simpelt.
Avatar billede arne_v Ekspert
12. oktober 2008 - 04:06 #3
Det kan laves *MEGET* pænere.

  while (true)
  {
      if (_smsQueue.Count > 0)
      {
        Console.WriteLine(_smsQueue.Dequeue());
      }
  }

vil æde 100% CPU mens køen er tom !
Avatar billede sph1nx Nybegynder
12. oktober 2008 - 11:14 #4
#Kalp
yes, har kigget lidt på MSMQ, har desværre bare ikke haft tid til at kode noget endnu..

#arne_v
Ja, ved det godt, det er ret skidt. hva ville du foreslå ?
Avatar billede arne_v Ekspert
12. oktober 2008 - 15:51 #5
Du skal have lavet en blocking queue !

Således at den der læser venter indtil der er noget uden at bruge CPU.

Jeg kan godt finde et eksempel hvis nødvendigt.
Avatar billede sph1nx Nybegynder
13. oktober 2008 - 10:14 #6
Må du meget gerne
Avatar billede arne_v Ekspert
13. oktober 2008 - 17:38 #7
For 3 år siden lavede jeg denne kode til et andet spørgsmål:

using System;
using System.Collections;
using System.Threading;

namespace E
{
    public abstract class Command
    {
        public abstract void Execute();
    }
    public class Test1Command : Command
    {
        private int v;
        public Test1Command(int v)
        {
            this.v = v;
        }
        public override void Execute()
        {
            Console.WriteLine("Test1 thread = " + Thread.CurrentThread.Name + " v = " + v);
        }
    }
    public class Test2Command : Command
    {
        private int v;
        public Test2Command(int v)
        {
            this.v = v;
        }
        public override void Execute()
        {
            Console.WriteLine("Test2 thread = " + Thread.CurrentThread.Name + " v = " + v);
        }
    }
    public class CommandQueue
    {
        private Queue q;
        public CommandQueue()
        {
            q = new Queue();
        }
        public void Enqueue(Command cmd)
        {
            Monitor.Enter(q);
            q.Enqueue(cmd);
            Monitor.PulseAll(q);
            Monitor.Exit(q);
        }
        public Command Dequeue()
        {
            Command cmd = null;
            do
            {
                Monitor.Enter(q);
                if(q.Count > 0)
                {
                    cmd = (Command)q.Dequeue();
                }
                else
                {
                    Monitor.Wait(q);
                }
                Monitor.Exit(q);
            } while(cmd == null);
            return cmd;
        }
    }
    public class WorkerThread
    {
        private CommandQueue cq;
        public WorkerThread(CommandQueue cq)
        {
            this.cq = cq;
        }
        public void Run()
        {
            while(true)
            {
                Command cmd = cq.Dequeue();
                cmd.Execute();
            }
        }
    }
    public class WorkerThreadPool
    {
        private WorkerThread[] wt;
        public WorkerThreadPool(int n, CommandQueue cq)
        {
            wt = new WorkerThread[n];
            for(int i = 0; i < wt.Length; i++)
            {
                wt[i] = new WorkerThread(cq);
                Thread t = new Thread(new ThreadStart(wt[i].Run));
                t.Name = "Thread-" + (i + 1);
                t.Start();
            }
        }
    }
    public class TestClass
    {
        public static void Main(string[] args)
        {
            CommandQueue qc = new CommandQueue();
            WorkerThreadPool wtp = new WorkerThreadPool(3, qc);
            qc.Enqueue(new Test1Command(1));
            qc.Enqueue(new Test2Command(2));
            qc.Enqueue(new Test1Command(3));
            qc.Enqueue(new Test2Command(4));
            Thread.Sleep(5000);
            Environment.Exit(0);
        }
    }
}
Avatar billede arne_v Ekspert
13. oktober 2008 - 17:39 #8
CommandQueue.Dequeue er blocking
Avatar billede sph1nx Nybegynder
14. oktober 2008 - 14:47 #9
#arne_v
det blev den løsning jeg brugte, så smid et svar
Avatar billede arne_v Ekspert
14. oktober 2008 - 15:01 #10
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester