gpt4 book ai didi

c# - 在 C# 中取消任务

转载 作者:行者123 更新时间:2023-11-30 23:18:32 26 4
gpt4 key购买 nike

我有一个带有两个按钮(开始停止)的表单。

当我按下 Start 按钮时,一个 Task 被初始化并调用一个函数,该函数一直运行直到按下 Stop 按钮。

但是当我按下停止 按钮时,表单会卡住。为什么?我从 StackOverflow 复制了片段但它仍然卡住表格。那么请告诉我如何正确取消任务?

public partial class Form1 : Form
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private Task _task;

public Form1()
{
InitializeComponent();
}

//Funtion that runs when Task is initialized.
private void EventLoop(CancellationToken token)
{
//Code here..
while (!token.IsCancellationRequested)
{
//Code here..
}
if (token.IsCancellationRequested)
{
MessageBox.Show("Operation Complete..!!");
}

}

//Function for Start Button.
private void Start_Click(object sender, EventArgs e)
{
_task = Task.Factory.StartNew(() => EventLoop(_cts.Token), _cts.Token);
}

//Function for Stop button.
private void Stop_Click(object sender, EventArgs e)
{
_cts.Cancel();
}
}

来自 MSDN 的类似示例:

var compute = Task.Factory.StartNew(() =>
{
return SumRootN(j);
}, tokenSource.Token);`

在按下停止 按钮后形成。token.IsCancellationRequestedtrue

Freeze Form

完整的 EventLoop() 函数。

private void EventLoop(CancellationToken token)
{
SerialPort sp = new SerialPort();
string text, batch, part, courseName;
text = batch = part = courseName = "";
int courseId = 0;

this.Invoke((MethodInvoker)delegate()
{
text = portCB.SelectedItem.ToString();
batch = comboBox2.SelectedItem.ToString();
part = comboBox3.SelectedItem.ToString();
courseName = comboBox1.SelectedItem.ToString();
progressBar1.Value = 20;
using (Model1 db = new Model1())
{
courseId = db.Courses.Where(c => c.Course_name.ToUpper() == courseName.ToUpper()).Select(c => c.Course_Id).Single();
}
});

sp.PortName = text;
sp.BaudRate = 9600;
sp.Open();

while (!token.IsCancellationRequested)
{
text = sp.ReadLine();

if (text.Contains("Found ID #"))
{
this.Invoke((MethodInvoker)delegate()
{
textBox2.Clear();
textBox2.Text = "Getting Registation ID.\n";
progressBar1.Value = 60;
});

string splitText = text.Split('#')[1];
int end = splitText.IndexOf(' ');
int id = int.Parse(splitText.Substring(0, end));

using (Model1 db = new Model1())
{
var result = db.Students.Where(s => s.Reg_Id == id && s.Batch == batch && s.Class == part).Select(s => s).SingleOrDefault();
if (result != null)
{
Attendance a = new Attendance();
a.Course_Id = courseId;
a.Student_Id = id;
a.Status = "P";
a.Date = DateTime.Today.Date;
a.Batch = batch;
a.Part = part;

db.Attendances.Add(a);
string message = "";

if (db.SaveChanges() != 0)
{
message = "Attendance Uploaded..!!\n";
}
else
{
message = "Attendance Not Uploaded ..!!\n";
}

this.Invoke((MethodInvoker)delegate()
{
progressBar1.Value = 100;
textBox2.AppendText(message);
});
}
else
{
this.BeginInvoke((MethodInvoker)delegate()
{
textBox2.AppendText("Student Does not belong to Specified Batch Or Part..\n");
});
}
}
}
else
{
this.Invoke((MethodInvoker)delegate()
{
textBox2.AppendText("No Match Found..!! \n");
});
}
this.Invoke((MethodInvoker)delegate()
{
textBox1.AppendText(text + "\n");
});
}
sp.Close();

// This exception will be handled by the Task
// and will not cause the program to crash
if (token.IsCancellationRequested)
{
//MessageBox.Show("Operation Comptele..!!");
}
}

最佳答案

您在取消过程中调用 MessageBox.Show("Operation Complete..!!");。强烈不建议这样做,这不是说您正在从 UI 线程以外的地方调用 UI 操作。

注释 MessageBox.Show("Operation Complete..!!");

* 编辑 *

问题作者对他的原始问题的评论,发现错误,从帖子中删除了哪一行。这是我的结论:

始终尝试隔离问题,并以最纯粹的形式重现。在此过程中,您可能会自行诊断并发现问题 :-)。

因此,如果有问题的代码很长,则绝对不是删除行然后发布的方法。方法是删除行并查看问题是否存在,换句话说:以最纯粹的可重现形式隔离问题

关于c# - 在 C# 中取消任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40839606/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com