我有一个在打开新表单实例时创建的线程。 此表单打开时,此线程应始终运行。 表单关闭后,它应该死掉。
问题是当我打开同一表单的新实例时,它使用相同的线程。
我正在寻找的正确代码可能就像我在想的那样......除非这是无效的:
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;
}
}
}
提前致谢!
答案 0 :(得分:7)
你可以用这个:
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
在这种情况下并不相关,但是当我使用线程(如客户端等)构建一些实例时,我会正常使用它。
该示例无异常处理。你应该添加try / finally。
这样你就可以完全控制线程上的作业,布尔检查是线程安全
整个事物可以包裹在一个新对象中。 :)