很抱歉没有经验丰富的多线程。通常我可以谷歌有效地找到我的答案,但我坚持这个。
我知道我可能会在这里使用背景工作者,但为了学习,我想知道如何以及如果可以手动完成这项工作?
只是尝试在按钮上启动一个线程,它运行一个方法循环来打印文本到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);
}
}
}
}
}
答案 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函数,则无法控制正在运行的代码。