简体   繁体   中英

Stopping a started thread method loop C#

Sorry not that experienced in multi-threading. Normally I can google effectively to find my answer but I'm stuck on this one.

I know I could probably use a backgroundworker here, but for the sake of learning I would like to know how and if this can be done manually?

Just trying to start a thread on button push that runs a method loop to print text to the gui, but cannot figure out how to stop this thread running. From what I can pick up, Thread.Abort is not a good way to do it?

using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Threading;

    namespace ThreadStopping
    {
        public partial class Form1 : Form
        {
            public bool isRunning;
            private static Thread neh;

            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {

            }

            private void button1_Click(object sender, EventArgs e)
            {
                StartThread();
            }

            private void button2_Click(object sender, EventArgs e)
            {
                StopThread();
            }

            private void StartThread()
            {

                neh = new Thread(Running);
                neh.Start();
                isRunning = true;
            }

            private void StopThread()
            {

                    isRunning = false;

            }

            private void runningText(int value)
            {
                if (this.InvokeRequired)
                    Invoke(new runningTextDelegate(runningText),value);
                else
                label1.Text = value.ToString();
            }

            delegate void runningTextDelegate(int value);

            void Running()
            {
                while (isRunning)
                {
                    for (int i = 0; i < 1000000; i++)
                    {
                        runningText(i);
                    }
                }

            }
        }
    }

use background worker instead-of thread

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        int p = 0;
        int high = 10000;
        do
        {
            for (int i = 0; i < high; i++)
            {
                if (i%10 == 0 && backgroundWorker1.CancellationPending)
                    break;

                if (i%100 == 0) // for performance purposes
                {
                    p = (int) ((float) i/high*100);

                    backgroundWorker1.ReportProgress(p, i);
                }
            }
        } while (!backgroundWorker1.CancellationPending);          

    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if(e.UserState!=null)
        label1.Text = e.UserState.ToString();
        progressBar1.Value = e.ProgressPercentage;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.CancelAsync();
    }

You are not synchronizing access to isRunning . This is a data race. Your reader thread might never pick up the write (on an instruction level it might be in a register).

Use a volatile variable, or Thread.VolatileRead/Write .

You can also just lock access to that variable. If you don't access it too often, you shouldn't worry about overhead too much. Fist concern is correctness (which you have struggled with).

Apart from that your code should be working.

Thread.Abort is indeed evil because code must be written to be safe under abortion at an arbitrary instruction. That's rarely the case and you cannot control what code is running if you call to BCL functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM