Click here to Skip to main content
15,567,466 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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.  Currently, I get an exception when I run it that says: System.InvalidOperationException: 'Cross-thread operation not valid; Control 'dataFileTextBox' accessed from a thread other than the thread it was created on'.


What I have tried:

I tried running it in a task, but currently I get the exception mentioned above. I tried CancellationTokenSource, but again, that didn't really help since I want to be able to change some of my form controls from within that task. I even tried passing in the control to the task, but that didn't work either.
Posted
Updated 22-Sep-21 6:27am

You can't stop the UI thread doing a long operation with a button, because the button click will not be processed until the long running job has completed.

The only way to do it is to move the code to a different thread, but then you can't access any controls at all on the new thread or you will get the cross threading excpetion you have seen.

There are two way round that:
1) Use a BackgroundWorker class[^] to handle the long running code, and pass the control update data back to the UI thread via the Progress reporting facility of the BackgroundWorker. This is normally pretty simple to do, and I do it a lot!
2) Invoke the control[^] to do the update which moves the update code back to the UI thread. That's messy, and can be cumbersome to read in code.
 
Share this answer
 
Yeah, this isn't a case where you get to do something simple and everything just works.

This is a case of completely redesigning what I think is your small app from the ground up with threading in mind.

ALL controls can only be accessed from the UI (startup) thread. If your "work" needs to update controls, any data must be marshaled back to the UI thread for a method to update the control.

This is not a simple change. This is not something where there's only one way to do things. There is no one specific anwer to get to this work.
 
Share this answer
 
Quote:
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.

Short answer: you need to move the long job in another thread.
The UI thread is what makes your app responsive in GUI.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900