Announcement

Collapse
No announcement yet.

thread beenden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • thread beenden

    hi ng

    mal wieder eine frage aus der einsteigerecke:

    ich habe mir ein programm geschrieben in dem ich einen worker thread
    verwende.

    starten und nutzen ist kein problem nur meine art den thread zu beenden ist
    glaub ich nicht die richtige.

    denn in den dokufensterchen kam der hinweiß das so der thread nur in der
    regel beendet wird. das ist mir nicht sicher genug darum bitte ich euch
    schaut euch kurtz mal den code an und sagt mir doch bitte ob ich noch ne
    andere variante nemen kann:

    vielen dank

    CODE:
    <PRE>
    private void BtnStart_Click(object sender, System.EventArgs e)
    {
    ThreadStart Worker = new ThreadStart(DoThread);
    Thread MyThread = new Thread(Worker);
    MyThread.Start();
    this.BtnEnde.Visible = true;
    }

    private void DoThread()
    {
    MessageBox.Show("Thread gestartet");
    BtnStart.Visible = false; //button wird ausgeblendet
    do
    {
    ListBox.Items.Add("Timer worked " + DateTime.Now.ToString());
    Thread.Sleep(1000);
    if(BtnEnde.Visible == false) Thread.CurrentThread.Abort();
    } while(true);
    }

    private void BtnEnde_Click(object sender, System.EventArgs e)
    {
    this.BtnEnde.Visible = false;
    this.BtnStart.Visible = true;
    }
    </PRE>

  • #2
    Hallo,

    ein zusätzlich abgespalteter Thread beendet sich selbst, wenn er seinen Job erledigt hat, d.h. die im obigen Beispiel genutzte Methode <i>DoThread</i> verlassen wird. Es reicht somit aus, einen Weg vorzusehen, wie die Schleife beendet werden kann.

    Das folgende Beispiel demonstriert einen der möglichen Wege: <br>
    a) Eine <b>AutoResetEvent</b>-Instanz kümmert sich um die Kommunikation zwischen primären Thread und 2. Thread <br>
    b) Das Flag <b>bShutDown</b> definiert die Ausstiegsbedingung aus der WHILE-Schleife<br>
    c) Wenn der 2. Thread gestoppt werden soll, setzt der primäre Thread das Flag <i>bShutDown</i> auf true und wartet auf das Ende des 2. Threads (Join). Damit der Thread seine Schleife verlassen kann, muss das Event gesetzt werden, bevor die Thread-Methode Join aufgerufen wird.
    <pre>
    using System;
    //
    using System.Threading;

    namespace CSharpThreadEvent
    {

    public class ThreadEventClass
    {
    private AutoResetEvent aARE;
    private bool bShutDown = false;
    private Thread aWrkThrd;
    private string sThrdData;

    public ThreadEventClass()
    {
    aARE = new AutoResetEvent(false);
    }

    public void StartWorkerThread()
    {
    aWrkThrd = new Thread(new ThreadStart(DoThreadWork));
    aWrkThrd.IsBackground = true;
    aWrkThrd.Start();
    }

    public void ShutDownWorkerThread()
    {
    bShutDown = true;
    aARE.Set();
    aWrkThrd.Join();
    }

    public void CallWorkerThread(string sMsg)
    {
    sThrdData = sMsg;
    aARE.Set();
    }

    private void DoThreadWork()
    {
    ThreadForm aThrdFrm = new ThreadForm();
    aThrdFrm.Show();
    do
    {
    // Thread wartet sofort auf ein Event!
    aARE.WaitOne();
    // Arbeiten oder Stoppen - das ist hier die Frage ?
    if (!bShutDown)
    {
    aThrdFrm.LogThreadMessage(sThrdData);
    System.Windows.Forms.Application.DoEvents();
    }
    }
    while (!bShutDown);
    aThrdFrm.Close();
    }

    }
    }
    </pre>
    Öffentliche Methode im Thread-Formular:
    <pre>
    private int iCnt;

    public void LogThreadMessage(string sMsg)
    {
    listBox1.Items.Add(sMsg);
    iCnt++;
    statusBar1.Text = string.Format("{0}. Aufruf",iCnt.ToString());
    }
    </pre>
    Aufruf im Hauptformular:
    <pre>
    private ThreadEventClass aThrd;

    private void buttonStart_Click(object sender, System.EventArgs e)
    {
    aThrd = new ThreadEventClass();
    aThrd.StartWorkerThread();
    statusBar1.Text = "Worker-Thread läuft...";
    }

    private void buttonStop_Click(object sender, System.EventArgs e)
    {
    aThrd.ShutDownWorkerThread();
    statusBar1.Text = "";
    }

    private void buttonDoWork_Click(object sender, System.EventArgs e)
    {
    aThrd.CallWorkerThread(DateTime.Now.ToString());
    }
    </pre>
    P.S: Auch unter .NET darf "offiziell" nur der Thread direkt auf Elemente der Benutzeroberfläche (Controls) zugreifen, der diese auch instanziert hat. Der Thread muss somit entweder <br>
    a) den Zugriff über <b>Invoke</b> umleiten, oder <br>
    b) die Formularinstanz direkt aus dem eigenen Thread heraus erzeugen <br>
    Mein Beispiel nutzt b) und erzeugt das Formular direkt aus dem zweiten Thread heraus, so dass der direkte Zugriff auf die Controls "legal" ist

    Comment


    • #3
      vieln dank andreas!

      das ist echt ein sehr cooles beispiel

      Comment

      Working...
      X