在usercontrol上运行单独的任务

时间:2018-03-29 11:15:00

标签: c# winforms ui-thread

我有一个UserControl项目,该项目由TextBoxButton和第三方地图控件组成。

我在TextBox中输入一个命令,点击Button,然后代码隐藏在Map control上做了很多工作。用户可以选择读取包含多个命令的文本文件,并逐行执行。

当用户想要取消当前读取文本文件/执行命令时,问题就出现了。他们希望能够在文本框中键入“取消”,点击按钮,然后停止所有执行。 GUI当然在执行命令时被冻结,因此用户不能输入“取消”并单击按钮来停止执行。

解决此问题的正确方法是什么?这是我的用户控件的代码隐藏:

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
}

因此用户键入Run,点击按钮,它会启动if / else语句的第一个块。我不希望文本框和按钮在执行时被阻止,并希望用户能够发送“取消”以便它停止运行部分。

编辑:更新了我的代码。我在Map.fresh()上遇到问题;它没有执行,只是说“线程已经退出代码0”。我猜这是因为它是UI线程的一部分。我是否必须在使用Map.Refresh()?

的每个方法上使用某种调用

1 个答案:

答案 0 :(得分:1)

如果您不希望在后台执行操作时阻止UI,则您必须异步执行操作。您可以使用非常简单易用的CancellationToken,并且可以使用where取消背景操作。

阅读本文:https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation