繁体   English   中英

关闭表单后杀死线程?

[英]Killing a thread after closing a form?

我有一个在打开新的表单实例时创建的线程。 打开此表单时,该线程应始终运行。 表格关闭后,它应该死亡。

问题是,当我打开相同形式的新实例时,它使用相同的线程。

我正在寻找的正确代码可能与我在想的类似……除非这是无效的:

t = new Task(Task.Factory.StartNew(() => totalDistance()));

这是完整的代码:WindowsFormClosing方法可能是不必要的,但是我没有主意。

    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;

    namespace ITS3_Eksamen_F2014_201270810
    {
    public partial class DistanceForm : Form
    {
        Data dat;
        private string name;
        Task t;
        private bool killThread;

        public DistanceForm(Data d, string n)
        {
            dat = d;
            name = n;
            InitializeComponent();
            getDistance(name);
            nameLabel.Text = name;
            t = Task.Factory.StartNew(() => totalDistance());
            killThread = false;
        }

        private void getDistance(string name)
        {
            var dList = new List<Distance>();
            dList = dat.getDistance(name);
            int i = 0;
            dataGridView1.Rows.Clear();
            foreach (Distance dist in dList)
            {
                dataGridView1.Rows.Add();
                dataGridView1.Rows[i].Cells[0].Value = dist.getTid();
                dataGridView1.Rows[i].Cells[1].Value = dist.getAngivelse();
                dataGridView1.Rows[i].Cells[2].Value = dist.getLængde();
                dataGridView1.Rows[i].Cells[3].Value = dat.getFullName(dist.getInitialer());
                i++;
            }
        }

        private void updateInitials(string initialer, int rowNumber)
        {
            dataGridView1.Rows[rowNumber].Cells[3].Value = dat.getFullName(initialer);
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            int rowNumber = dataGridView1.CurrentCell.RowIndex;

            if (!dataGridView1.Rows[rowNumber].Cells[0].Value.ToString().Equals("") 
                && !dataGridView1.Rows[rowNumber].Cells[1].Value.ToString().Equals("") 
                && !dataGridView1.Rows[rowNumber].Cells[2].Value.ToString().Equals("")
                && !dataGridView1.Rows[rowNumber].Cells[3].Value.ToString().Equals(""))
            {
                var tid = dataGridView1.Rows[rowNumber].Cells[0].Value.ToString();
                var længde = dataGridView1.Rows[rowNumber].Cells[1].Value.ToString();
                var angivelse = dataGridView1.Rows[rowNumber].Cells[2].Value.ToString();
                var initialer = dataGridView1.Rows[rowNumber].Cells[3].Value.ToString();
                dat.addDistance(name, tid, længde, angivelse, initialer);
            }
            else
            {
                MessageBox.Show("Du skal udfylde alle felter!");
            }
            int currentRow = dataGridView1.CurrentCell.RowIndex;
            string currentRowInitialer = dataGridView1.Rows[currentRow].Cells[3].Value.ToString();
            updateInitials(currentRowInitialer, currentRow);
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            int number = dataGridView1.CurrentCell.RowIndex;
            dat.deleteDistance(name, number);
        }

        private void totalDistance()
        {
            while (killThread == false)
            {
                int totalDist = 0;
                int newDist = 0;
                var testList = dat.getDistance(name);
                foreach (Distance dist in testList)
                {
                    newDist = Convert.ToInt32(dist.getLængde().Replace(" km", ""));
                    totalDist = totalDist + newDist;
                }

                this.BeginInvoke((Action)(() =>
                    {
                        textBox1.Text = Convert.ToString(totalDist) + " km";
                    }));
            }
        }

        private void WindowsFormClosing(object sender, FormClosingEventArgs e)
        {
            killThread = true;
        }
    }
}

提前致谢!

您可以使用此:

private Thread _thread;

public DistanceForm()
{
    InitializeComponent();

    _thread = new Thread(new ThreadStart(totalDistance));
    _thread.Start();
}

public void FormClosed(object sender, EventArgs e)
{
    killThread = true;
    _thread.Join();
}

我建议不要使用布尔值,而建议使用ManualResetEvent。

喜欢:

private Thread _thread;
private ManualResetEvent _started = new ManualResetEvent(false);
private ManualResetEvent _terminating = new ManualResetEvent(false);
private ManualResetEvent _terminated = new ManualResetEvent(false);

public void InitializeComponent()
{
    _thread = new Thread(() => totalDistance());
    _thread.Start();

    // wait until the thread is started.
    _started.WaitOne();
}

private void totalDistance()
{
    // do some initialization stuff..

    // Set started.
    _started.Set();
    while(!_terminating.WaitOne(0))
    {
        // ...
    }
    _terminated.Set();
}

public void FormClosed(object sender, EventArgs e)
{
    // request for terminating.
    _terminating.Set();
    // wait until it's terminated.
    _terminated.WaitOne();
}

started并不在此情况有关,但我通常使用它时,某些情况下构建withing线程(如客户等)

该示例没有异常处理。 您应该添加try / finally。

这样,您就可以完全控制线程上的作业,并且布尔检查是线程安全的

整个东西可以包装在一个新对象中。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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