pfinferno
pfinferno

Reputation: 1945

Running separate task on usercontrol

I have a UserControl project which is comprised of a TextBox, a Button, and a third party Map control.

I type a command in the TextBox, click the Button, and the code-behind does a bunch of work on the Map control. The user has the option of reading a text file, which contains multiple commands, and executes them line by line.

The problem comes when the user wants to cancel the current reading of the text file/execution of the commands. They want the ability to type in 'Cancel' in the textbox, hit the button, and stop all execution. The GUI of course is frozen when executing the commands, so the user can't type "Cancel" and click the button to stop the execution.

What's the proper way to solve this issue? Here's the code-behind for my user control:

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
}

So the user types Run, hits the button, it launches the first block of the if/else statement. I don't want the textbox and button to be blocked while it's executing, and want the user to be able to send "Cancel" so it stops the Run part.

Edit: Updated my code. I'm having problem on the Map.Refresh(); It doesn't execute, just says "thread has exited with code 0". I'm guessing this is because it's part of the UI thread. Would I have to use some sort of invoke on every method that uses the Map.Refresh() ?

Upvotes: 0

Views: 335

Answers (1)

Maverick
Maverick

Reputation: 801

If you don't want UI to be blocked while the operations are performed in the background, you'll have to perform the operations asynchronously. You can use Tasks which are quite simple to use and you can use CancellationToken to cancel the backround operation.

Read This : https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation

Upvotes: 1

Related Questions