Avatar billede anadan Nybegynder
07. september 2005 - 10:19 Der er 9 kommentarer og
1 løsning

Bedste måde at genbruge tråde

Jeg sidder og laver lidt trådprogrammering.

Jeg har af forskellige årsager brug for to tråde der skiftes. Jeg har derfor puttet dem i et array, Thread[2].

Problemet er at hvis jeg prøver at kalde Start() på en der allerede har kørt, vil den smide en ThreadStateException, da man ikke kan genstarte en tråd.

Er jeg virkelig nødt til at initialisere en ny tråd hver gang, eller findes der en bedre metode?
Avatar billede arne_v Ekspert
07. september 2005 - 10:28 #1
du kan lave en ny

eller du kan lave dine tråde som worker threads der henter et task fra
en queue, udfører den og så henter næste task (blokerer hvis der ikke
er noget task der skal udføres)

jeg mener faktisk at der er indbygget noget thread pool i .NET, men det har jeg aldrig
prøvet at bruge
Avatar billede anadan Nybegynder
07. september 2005 - 10:33 #2
Der er altså ingen måde at "resette" en tråd? Jeg arbejder med compact frameworket, så det er ikke optimalt at oprette nye tråde. Og jeg tror ikke at det er muligt at lave worker threads, eller bruge threadpool, på grund af funktionaliteten
Avatar billede arne_v Ekspert
07. september 2005 - 10:37 #3
hvis threads er supporteret og hvis lock er supporteret så kan man lave
sin egen thread pool med en blocking queue med tasks
Avatar billede anadan Nybegynder
07. september 2005 - 10:49 #4
Har du et eksempel, så får du point
Avatar billede rbj_fp Nybegynder
07. september 2005 - 10:59 #5
Avatar billede arne_v Ekspert
07. september 2005 - 11:04 #6
jeg kan lave et eksempel - en thread pool + en blocking queue + command pattern
er ofte en fornuftig løsning

men det bliver i givet fald først i aften
Avatar billede arne_v Ekspert
07. september 2005 - 21:17 #7
her er et eksempel i "java style":

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 anadan Nybegynder
07. september 2005 - 21:34 #8
Det ser simpelt nok ud. Jeg tjekker lige om jeg kan få det til at passe ind i min kode, i mellemtiden kan du lige smide et svar.
Avatar billede arne_v Ekspert
07. september 2005 - 21:38 #9
svar

det er helt standard - den slags kode må være skrevet masser af gange i alle mulige
sprog
Avatar billede anadan Nybegynder
07. september 2005 - 23:34 #10
Ja, men spørgsmålet er om det løser mit problem. Anyway, takker
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