Avatar billede hehe7777 Nybegynder
05. marts 2008 - 14:36 Der er 9 kommentarer og
1 løsning

Threading Join

Håber en eller anden kan hjælpe mig med lidt threading:

Når jeg kører nedennævnte ex i en Console aplikation (statiske metoder), så termineres trådene godt nok efter join.
using System;
using System.Threading;

class MainClass
{
    public static void Main(string[] args)
    {
        Thread[] t = new Thread[10];
        for(int i = 0; i < t.Length; i++) {
            t[i] = new Thread(new ThreadStart(DoSomething));
        }
        for(int i = 0; i < t.Length; i++) {
            t[i].Start();
        }
        for(int i = 0; i < t.Length; i++) {
            t[i].Join();
        }
    }
    public static void DoSomething()
    {
        Console.WriteLine("start");
        Thread.Sleep(5000);
        Console.WriteLine("end");
    }
}

Hvis jeg kører det i en WinForm aplikation med en knap og en richtextbox(rtb) så hænger aplikation i Join.
ex 1:
namespace ThreadingWinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
   
        private void button1_Click(object sender, EventArgs e)
        {
            Thread[] t = new Thread[10];
            for (int i = 0; i < t.Length; i++)
            {
                t[i] = new Thread(new ThreadStart(DoSomething));
                t[i].Name = "ID " + i.ToString();
            }
            for (int i = 0; i < t.Length; i++)
            {
                t[i].Start();
            }
            for (int i = 0; i < t.Length; i++)
            {
                t[i].Join();
            }

        }
        delegate void UpdateRTBDelegate(string _text);
        private void UpdateRTB(string _text)
        {
            if (this.rtb != null)
            {
                if (this.rtb.InvokeRequired)
                {
                    this.rtb.Invoke(new UpdateRTBDelegate(UpdateRTB), _text);
                }
                else
                {
                    this.rtb.AppendText(_text + "\n");
                    this.rtb.ScrollToCaret();
                    this.rtb.Refresh();
                }
            }
        }

        public void DoSomething()
        {
            UpdateRTB("start - " + Thread.CurrentThread.Name);
            Thread.Sleep(5000);
            UpdateRTB("end - " + Thread.CurrentThread.Name);
            //UpdateRTB("Join - " + Thread.CurrentThread.Name);
            //Thread.CurrentThread.Join();
        }

    }
}
ex 2:
Så prøvede jeg at flytte Join ned i DoSomething, men så hænger aplikationen når jeg lukker den.

        private void button1_Click(object sender, EventArgs e)
        {
            Thread[] t = new Thread[10];
            for (int i = 0; i < t.Length; i++)
            {
                t[i] = new Thread(new ThreadStart(DoSomething));
                t[i].Name = "ID " + i.ToString();
            }
            for (int i = 0; i < t.Length; i++)
            {
                t[i].Start();
            }
            //for (int i = 0; i < t.Length; i++)
            //{
            //    t[i].Join();
            //}

        }
        public void DoSomething()
        {
            UpdateRTB("start - " + Thread.CurrentThread.Name);
            Thread.Sleep(5000);
            UpdateRTB("end - " + Thread.CurrentThread.Name);
            UpdateRTB("Join - " + Thread.CurrentThread.Name);
            Thread.CurrentThread.Join();
        }

Hvad er det der gør at trådene ikke termineres? Jeg kan selvfølgelig bruge Abort() istedet, eller sætte et Timespan i Join. Men er det ikke Join man helst skal bruge?
Avatar billede kalp Novice
05. marts 2008 - 17:52 #1
prøv at tilføje volatile til din DoSomething metode.
Avatar billede kalp Novice
05. marts 2008 - 17:54 #2
men problemet må ellers ligge i, at formen kører sin egen tråd..
men istedet for join så prøv, at kalde RequestStop();
Avatar billede kalp Novice
05. marts 2008 - 17:56 #3
eller kald RequestStop() før Join() og behold begge.
Avatar billede hehe7777 Nybegynder
05. marts 2008 - 20:10 #4
tak for kommentaren kalp. Jeg kan desværre først prøve det imorgen.
Men jeg vender tilbage
Avatar billede hehe7777 Nybegynder
06. marts 2008 - 09:16 #5
Hvordan skal RequestStop() kaldes. Det er ikke en mulig metode at kalde på tråden.
Det nemmeste er nok at bruge Join(Timespan). Det fungerer og DoSomething har gjort det den skulle.
Men det er for min egen forståelses skyld.
Jeg forstår ikke hvorfor det fungerer med statiske metoder, mem ikke ellers. Og det irreterer mig når jeg ikke forstår det.
Avatar billede kalp Novice
07. marts 2008 - 01:51 #6
har du prøvet om det hjælper hvis du benytter dig af ThreadPool ?
Avatar billede hehe7777 Nybegynder
11. marts 2008 - 11:04 #7
nej det har jeg ikke. jeg bruger Join(Timespan). det er nemmest. Men tak for hjælpen anyway
Avatar billede wisen Nybegynder
13. marts 2008 - 08:40 #8
Du kan prøve at sætte Thread.IsBackground...
http://msdn2.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

"A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete."
Avatar billede wisen Nybegynder
13. marts 2008 - 08:42 #9
.. jeg kan ikke lige lure hvorfor dine tråde ikke terminerere - men når du kalder Thread.Join så vil kaldet blokere indtil den tråd du kalder terminerer. Ved at bruge Thread.Join( TimeSpan ), kan du angive hvor lang tid du ønsker at vente på at den pågældende tråd bliver færdig.

Som sagt kan jeg ikke lige lure hvorfor trådene ikke terminerer - men måske har det noget med kaldet til Invoke at gøre?!?

/Wisen
Avatar billede hehe7777 Nybegynder
01. september 2010 - 10:18 #10
skal lige lukke denne tråd
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