I have a windows form that has (among other things) a Start and a Stop button. If the Start button_click code takes too long, I'd like to press the stop button (or some other event) that will allow me to stop that code from completing. The question is about not having to wait for that code to complete before the UI thread will allow the processing of the Stop button_click code. As I tried looking up an answer to my problem, some of the thread sleep, interrupt and abort info didn't seem to be applicable. Once the start button is pressed, and it runs the code in my Start Button_click event handler, I'd like to be able to initiate an event that would then stop the running of that code. I tried running all that code (in the Start Button_click event handler) in a task using Async and Await, but that didn't work because that code tries to update and change some of the text boxes on my form that were created in the main UI thread. And since that Start button code takes a while to complete, I'm not sure how to initiate a stop event that will allow me to stop the currently running code.

- 113,464
- 11
- 89
- 172

- 183
- 1
- 1
- 9
-
Code is always appreciated. – Enigmativity Sep 22 '21 at 04:42
-
Also, showing what you've tried allows us to help you solve it. – Enigmativity Sep 22 '21 at 04:43
-
Right now, the best answer is that you need to co-operatively close your code down. A `CancellationToken` is what you need. – Enigmativity Sep 22 '21 at 04:44
1 Answers
The correct way to do this is to separate any time consuming code from code that updates the UI. Possibly with some interface or adapter class to update things like progress or logging.
Then you should run the time consuming asynchronously with cancellation. If it is compute bound it is typical to run it on a background thread with Task.Run(...)
. To make cancellation work, create a TaskCancellationSource
when starting the task, and hand its token to the task. The task should then check this token regularly, for example by calling ThrowIfCancellation
, just ensure you catch OperationCancelledException
when awaiting the task. For IO bound tasks you can in theory do the same, just give the IO operation the CancelationToken
instead, but some IO operation seem to run synchronously in practice.
Then your stop button can simply call the cancel method for the TaskCancellationSource
This may seem like a lot of code, but it is kind of required if you want cancellation to work propperly.

- 28,608
- 2
- 10
- 23
-
I tried putting it in a Task, but since I want to make changes to some of the controls on my form, it won't let me (from a different thread). So It won't even run. It comes up with a System.InvalidOperationException: 'Cross-thread operation not valid: Control 'dataFileTextBox' accessed from a thread other than the thread it was created on.' – mdmenard Sep 22 '21 at 13:35
-
@mdmenard As I mention, you have to separate UI-code from computational code, and this is good practice regardless. And if you await the task you should be back on the main thread and can update the UI again. – JonasH Sep 22 '21 at 14:21
-
@mdmenard - I asked for code 17 hours ago. You posted this comment 8 hours ago, but there's no code. But your comment specifically addresses parts of your code. Please help us to help you by posted a [mcve] in your question. – Enigmativity Sep 22 '21 at 22:09
-
@mdmenard - I'm happy to re-open if you make the question answerable. – Enigmativity Sep 22 '21 at 22:09