C # Threading Run and Cancel button should be able to cancel a long run

When the user clicks the Run button, the application runs a lot of code to create the model and display it in the diagram. Launch takes about 1-2 minutes. I also have a Cancel button, which is activated after clicking the Run button. I work with DotSpatial, so my buttons are on the plugins panel in the ribbon interface. The start and cancel click event is fired in the plugin, which calls the code of the Back-End Run and Click class.

When the user clicks on cancel after start, there is a delay, but the cancel method starts and executes, but the execution never stops, and in the end we see the chart display. So, I think I need a separate thread for Run. I am new to programming and have never worked with Threading. I looked through it and added the code below, but my stream method does not work. Here is my code:

Click the Run button:

This is at the top:

//check to see if RunModel thread needs to stop or continue private volatile bool stopRun = false; private Thread runThread; 

Then this is the method invoked from the click event:

 public void btnRun_testingThread(object sender, EventArgs e) { //create a new thread to run the RunModel if (runThread == null) { //we don't want to stop this thread stopRun = false; runThread = new Thread(RunModel); runThread.Start(); <--this isn't doing anything } 

So, I think that when the code gets into runThread.Start (), it will go into my RunModel method and start working through the code. But this is not so. Also, I want to cancel this thread (as soon as I process it correctly), so I have this one that is called from the cancel click method:

 private void StopRunThread() { if (runThread != null) { //we want to stop the thread stopRun = true; //gracefully pause until the thread exits runThread.Join(); runThread = null; } } 

Then it's RunModel (), where I sometimes check if the stopRun bool parameter has changed.

 public void RunModel() { ...some code..... //check to see if cancel was clicked if (stopRun) { ....clean up code.... return; } ....some more code.... //check to see if cancel was clicked if (stopRun) { ....clean up code.... return; } } 

And the method of pressing the cancel button:

 public void btnCancel_Click(Object sender, EventArgs e) { stopRun = true; StopRunThread(); //the model run has been canceled ....some code..... } 

Any help on getting thread.start to actually run the Run method? Then I need to constantly check the volatile bool at startup to clear everything if it is stopped? Thanks!

+3
source share
2 answers

I think you're best off looking at BackgroundWorker - this essentially works separately, but can follow undo commands. Be sure to add "WorkerSupportCancellation" when you initialize it:

 BackgroundWorker backgroundWorker1 = new BackgroundWorker(); backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); // This does the job ... backgroundWorker1.WorkerSupportsCancellation = true; // This allows cancellation. 

Then, with a click, you can start your process:

 public void btnRun_testingThread(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } 

The cancel button may issue a cancel request:

 public void btnCancel_Click(Object sender, EventArgs e) { backgroundWorker1.CancelAsync(); } 

Then your worker can keep track of this, as it works ...

 void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i < 100; i++) { if (backgroundWorker1.CancellationPending) { break; } else { // Do whatever you're doing. } } e.Result = backgroundWorker1.CancellationPending ? null : orders; } 

You can improve this by adding progress bars, etc., but it gets a little more complicated, so I won’t go into it here.

+3
source

Given the new information provided in the comment, I believe that you simply missed the start of the RunModel() method in the debugger due to the incorrect assumption about the behavior of the thread.Start() method.

See MSDN Note, Thread.Start Method

Once the thread is in the ThreadState.Running state, the system can schedule it to run . The thread begins to execute in the first line of the method represented by ThreadStart or the Parameterized DelegateThreadStart provided to the thread constructor.

A small demonstration that the start of a stream takes several bits of time, for me it starts in 38-40 milliseconds:

 Stopwatch watch = new Stopwatch(); Thread thread = new Thread((ThreadStart)watch.Stop); thread.Start(); watch.Start(); Thread.Sleep(5000); double startedAfter = watch.ElapsedMilliseconds; 

Since the .NET Framework 4.0 considers using TPL Tasks rather than threads explicitly, some pros:

  • You can easily synchronize with the UI thread by passing the UI thread synchronization context to the Task
  • You can easily stop Taks using CancellationToken
0
source

Source: https://habr.com/ru/post/1484771/


All Articles