There is a _updater.Update() method; It runs a separate thread, which is engaged in checking for updates. I want to stop its execution by pressing the button

 private void breakBtn_Click(object sender, RoutedEventArgs e) { // что тут должно быть? } 

That is, I need to interrupt the work of a separate thread. Tell me how can I do this?

  • add the _updater.Update method. Generally - no way - Grundy
  • Unfortunately you did not understand .. private void breakBtn_Click (object sender, RoutedEventArgs e) {_updater.Update (); } if I do this, I will call the method, but I need to stop its implementation - Max Fadeev
  • You did not understand this :-) I meant: add the code of this function to the post, and also add what _updater is - Grundy
  • in _updater.Update () starts Thread / Task? - Stack
  • Or I did not understand) The code is very large. The class contains methods for checking for updates, updating itself, resuming the file. And I call him like this - _updater.Update (); In this method, there is a thread pool ThreadPool.QueueUserWorkItem (unused => - Max Fadeev

3 answers 3

A CancellationToken is passed to Thread or Task and its IsCancellationRequested property is checked. If true, then you must complete the work.

 using System.Threading.Tasks; using System.Threading; partial class MainWindow : Window { CancellationTokenSource cts; Model m; public MainWindow() { cts = new CancellationTokenSource(); this.DataContext = m = new Model(); m.Update(cts.Token); } private void Button_Click(object sender, RoutedEventArgs e) { cts.Cancel(); } } class Model : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = delegate { }; public void Update(CancellationToken ct) { var c = SynchronizationContext.Current; // запомнить текущий поток Task.Run(() => { // работаем пока не будет вызван cts.Cancel() while (ct.IsCancellationRequested == false) { c.Post(o => { // передать данные в основной поток this.State = o.ToString(); PropertyChanged(this, new PropertyChangedEventArgs("State")); } , DateTime.Now.Ticks); Task.Delay(500).Wait(); } }, ct); } public string State { get; private set; } } 

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="300" Height="300"> <StackPanel> <TextBlock Text="{Binding State}" /> <Button HorizontalAlignment="Left" Click="Button_Click" Content="Cancel" /> </StackPanel> </Window> 
  • CancellationToken solves the question posed by the author, but in my opinion it will not help him in his particular case. Tinkering with someone else's code, understanding logic, is lazy, so I hope that the author himself will figure out how the program should behave when trying to stop updating. Or there is not even a need for termination, but a pause. - Monk

Without knowing the method code, it’s hard to suggest an option, but in general, get a variable (bool) that both methods will see (doing work and interrupts). When starting the executing method, assign the variable to false (meaning not to interrupt) and as the method runs, check if the state of the variable has changed to true; if it has changed, then abort the method. And in the interrupting method you assign true and that's it.

 private bool _cancellation; public void Start() { _cancellation = false; // если _cancellation == true прерываемся while(!_cancellation) { // тут выполняем работу Thread.Sleep(10); } } public void Cancel() { _cancellation = true; } 

Such an option will enable the correct and importantly controlled completion of the method.

I described the general principle, it can be modified for threads and other things, this is a general principle for correctly interrupting the execution of a method.

  • I will try, on the basis of your answers, to come up with something. Thank you all for your responsiveness! - Max Fadeev
  • one
    while - for cyclic operations. Timer, in fact. And what about one but a long operation? It is clear that this is more convenient, but under the case how to fasten - I have something without a clue. - Monk
  • @Monk: put checks in those places where you can stop without leaving the system in an unhealthy state. - Nick Volynkin
  • While this is a simple example of work, no matter what you do in a method, run through a cycle or something else, the most important thing from time to time is to check the _cancellation condition. If true means it's time to finish with work and go out. In this case, you yourself in the method control when it is done (you can and not interrupt if you have a little bit left to complete). Having met _cancellation == true you have a lot of options, stop now, record intermediate results of the work, which would then continue from the same place and so on. - Eugene
  • one
    That's right, I suggest the button "Try to cancel." If the working method is hung, then these are problems of the logic of this method and in the conscience of the programmer. Just in the method that does the work and it is necessary to check whether its logic does not hang, this method should do all the checks so that only in this method it is possible to accurately determine the conditions of the interruption. - Eugene

I agree with @Monk, you first need to create a stream, and then when you click on the button, destroy it.

 Thread action; ... action = new Thread(() => { _updater.Update(); }); action.Start(); ... private void breakBtn_Click(object sender, RoutedEventArgs e) { try { action.Abort(); } catch(ThreadAbortException exc) {} } 

However, interrupting threads is not recommended; Sleep() , Join() - please, but not Abort()

  • The code that I sent, it creates a pool of threads .. Maybe there is another option? For example, write a method of completion or a pause in the class that is responsible for the update, and call it? .. only again I do not understand - Max Fadeev
  • 2
    @ MaksFadeev So it should be. No abortions. - Sergey
  • Rough flow interruption is bad. You are leaving the system in an unknown state. - Nick Volynkin
  • 3
    Even for training purposes, it is not worth killing streams, there are quite a few cases in which it is good to kill a stream, but it is practically not encountered in applied development. - Eugene
  • one
    @EvgeniyG I do not know what application you have, but closing the window \ application should close everything behind it. And if something is done in separate streams - then not to wait for them, when their results are no longer needed? It depends on the case, of course, but Abort is quite an option. - Monk