运行 用户控件上的单独任务
Running separate task on usercontrol
我有一个 UserControl
项目,它由一个 TextBox
、一个 Button
和一个第三方地图控件组成。
我在 TextBox
中键入一个命令,单击 Button
,然后代码隐藏在 Map control
上做了很多工作。用户可以选择读取包含多个命令的文本文件,并逐行执行它们。
当用户想要取消当前阅读命令的文本file/execution时,问题就来了。他们希望能够在文本框中输入 'Cancel',点击按钮,然后停止所有执行。 GUI当然在执行命令时被冻结,所以用户不能输入"Cancel"然后点击按钮停止执行。
解决这个问题的正确方法是什么?这是我的用户控件的代码隐藏:
private void RunScript(string[] command)
{
string filePath = command[1];
Task task = Task.Factory.StartNew(() => { ReadFile(ct, filePath);
}
private void ReadFile(CancellationToken token, string filePath)
{
using (var file = File.OpenText(filePath))
{
string line;
while ((line = file.ReadLine()) != null)
{
if (ct.IsCancellationRequested)
{
ct.ThrowIfCancellationRequested();
}
else
{
if (line == string.Empty || line.StartsWith("//"))
continue;
CallCommands(commandParser.StartParse(line));
}
}
}
tokenSource.Dispose();
}
private void CancelScript()
{
tokenSource.Cancel();
}
private void CallCommands(string command)
{
//do stuff to the Map control. ex:
Map.Refresh(); //problem here
}
所以用户键入 运行,点击按钮,它会启动 if/else 语句的第一个块。我不希望文本框和按钮在执行时被阻止,并希望用户能够发送 "Cancel" 所以它会停止 运行 部分。
编辑:更新了我的代码。我在 Map.Refresh(); 上遇到问题;它不执行,只是说 "thread has exited with code 0"。我猜这是因为它是 UI 线程的一部分。我是否必须对使用 Map.Refresh() 的每个方法使用某种调用?
如果您不希望 UI 在后台执行操作时被阻塞,则必须异步执行操作。可以使用Tasks
,使用起来非常简单,也可以使用CancellationToken
来取消后台操作。
读这个:https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation
我有一个 UserControl
项目,它由一个 TextBox
、一个 Button
和一个第三方地图控件组成。
我在 TextBox
中键入一个命令,单击 Button
,然后代码隐藏在 Map control
上做了很多工作。用户可以选择读取包含多个命令的文本文件,并逐行执行它们。
当用户想要取消当前阅读命令的文本file/execution时,问题就来了。他们希望能够在文本框中输入 'Cancel',点击按钮,然后停止所有执行。 GUI当然在执行命令时被冻结,所以用户不能输入"Cancel"然后点击按钮停止执行。
解决这个问题的正确方法是什么?这是我的用户控件的代码隐藏:
private void RunScript(string[] command)
{
string filePath = command[1];
Task task = Task.Factory.StartNew(() => { ReadFile(ct, filePath);
}
private void ReadFile(CancellationToken token, string filePath)
{
using (var file = File.OpenText(filePath))
{
string line;
while ((line = file.ReadLine()) != null)
{
if (ct.IsCancellationRequested)
{
ct.ThrowIfCancellationRequested();
}
else
{
if (line == string.Empty || line.StartsWith("//"))
continue;
CallCommands(commandParser.StartParse(line));
}
}
}
tokenSource.Dispose();
}
private void CancelScript()
{
tokenSource.Cancel();
}
private void CallCommands(string command)
{
//do stuff to the Map control. ex:
Map.Refresh(); //problem here
}
所以用户键入 运行,点击按钮,它会启动 if/else 语句的第一个块。我不希望文本框和按钮在执行时被阻止,并希望用户能够发送 "Cancel" 所以它会停止 运行 部分。
编辑:更新了我的代码。我在 Map.Refresh(); 上遇到问题;它不执行,只是说 "thread has exited with code 0"。我猜这是因为它是 UI 线程的一部分。我是否必须对使用 Map.Refresh() 的每个方法使用某种调用?
如果您不希望 UI 在后台执行操作时被阻塞,则必须异步执行操作。可以使用Tasks
,使用起来非常简单,也可以使用CancellationToken
来取消后台操作。
读这个:https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation