A
A
artshelom2019-03-27 23:27:07
C++ / C#
artshelom, 2019-03-27 23:27:07

How to stop the flow?

I'm trying to stop the thread:

wait.Stop = delegate ()
      {
        myThread.Abort();
      };
      myThread.Start();

In the shape of:
public Action Worker { get; }
    public Action Stop { get; set; }
    private Thread thread;
    public FormWait(Action worker)
    {
      InitializeComponent();
      if (worker == null)
        throw new ArgumentNullException();
      Worker = worker;
    }
    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);
      //thread = new Thread(new ThreadStart(delegate ()
      //{
      //	Worker();
      //}));
      //thread.Start();
      Task.Factory.StartNew(Worker).ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
    }

    private void button1_Click(object sender, EventArgs e)
    {
      Console.WriteLine("Stop");
      Stop();
    }

But for some reason it does not work, how can I stop the flow?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Pavlov, 2019-03-28
@lexxpavlov

You need to stop the flow not by killing it, but by stopping it, preferably from the inside. And in order to be able to do this, you need to pass a stop token inside. The break itself does nothing, but it is used inside the body of the thread to cancel or abort. This token will be passed to the Worker, which will need to check for a break using cancellationToken.IsCancellationRequested. If the worker uses a loop, then you can check in each iteration.

var formWait = new FormWait(cancellationToken => 
{
    foreach(var item in _items)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            return;
        }
        item.DoWork();
    }
});

wait.Stop = delegate ()
      {
        var source = _tokenSource;
        if (source != null)
        {
            source.Cancel();
            source.Dispose();
            _tokenSource = null;
        }
      };
      myThread.Start();

В форме:
    public Action<CancellationToken> Worker { get; } // добавляем ссылку на токен останова
    public Action Stop { get; set; }
    private CancellationTokenSource _tokenSource;
    public FormWait(Action<CancellationToken> worker)
    {
      InitializeComponent();
      if (worker == null)
        throw new ArgumentNullException();
      Worker = worker;
    }
    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);
      _tokenSource?.Dispose();
      _tokenSource = new CancellationTokenSource();
      var cancellationToken =  = _tokenSource.Token;
      Task.Factory.StartNew(() => Worker(cancellationToken ))
          .ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
    }

    private void button1_Click(object sender, EventArgs e)
    {
      Console.WriteLine("Stop");
      Stop();
    }

Perhaps it's good to do a task with a return result, for example
public Func<CancellationToken, bool> Worker { get; }

Task.Factory.StartNew<bool>(() => Worker(cancellationToken))
.ContinueWith(t => { if (t.Result) this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question