停止启动的线程方法循环C#

时间:2014-01-26 14:37:54

标签: c#

很抱歉没有经验丰富的多线程。通常我可以谷歌有效地找到我的答案,但我坚持这个。

我知道我可能会在这里使用背景工作者,但为了学习,我想知道如何以及如果可以手动完成这项工作?

只是尝试在按钮上启动一个线程,它运行一个方法循环来打印文本到gui,但是无法弄清楚如何阻止这个线程运行。从我能拿到的东西,Thread.Abort不是一个好方法吗?

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);
                    }
                }

            }
        }
    }

2 个答案:

答案 0 :(得分:0)

使用后台工作者代替线程

    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();
    }

答案 1 :(得分:0)

您没有同步isRunning的访问权限。这是一场数据竞赛。您的读者线程可能永远不会接受写入(在指令级别上它可能在寄存器中)。

使用易变变量或Thread.VolatileRead/Write

您也可以锁定对该变量的访问权限。如果你不经常访问它,你不应该担心过多的开销。拳头关注是正确的(你一直在努力)。

除了您的代码应该正常工作。

Thread.Abort确实是邪恶的,因为代码必须在任意指令的堕胎下被编写为安全的。这种情况很少发生,如果您调用BCL函数,则无法控制正在运行的代码。