Home > OS >  How to stop execution of some code to stop its execution immediate in .Net?
How to stop execution of some code to stop its execution immediate in .Net?

Time:09-24

I have library that can run for up to 30 minutes or even more.

In my client code i want to have opportunity to stop working of library's instance; Hot can i do it?

For example

 public class TickMe
    {
        public void Run()
        {
            int i = 0;
            while (true)
            {
                Thread.Sleep(1000);
                Console.WriteLine("tik"   i);
                i  ;
            }
        }
    }

And client code:

public class Client
{
  protected TickMe instance;
  public void Run()
  {
     TickMe instance = new TickMe();
     instance.Run();
  }

  public void Kill()
  {
    instance?????
  }
}

So what code i need to put in method Kill() to stop working instance of class TickMe ?

CodePudding user response:

You need something that doesn't block the current thread and to exit the while-loop.

You could try something like this:

public class TickMe
{
    private CancellationTokenSource _cancellationTokenSource;

    public async Task Start()
    {
        _cancellationTokenSource = new CancellationTokenSource();

        int i = 0;
        while (!_cancellationTokenSource.IsCancellationRequested)
        {
            await Task.Delay(1000, _cancellationTokenSource.Token);
            Console.WriteLine("tik"   i);
            i  ;
        }

        _cancellationTokenSource = null;
    }

    public void Stop()
    {
        _cancellationTokenSource?.Cancel();
    }
}

public class Client
{
    protected TickMe _instance;

    public async Task Run()
    {
        _instance = new TickMe();
        await _instance.Start();
    }

    public void Kill()
    {
        _instance.Stop();
    }
}

CodePudding user response:

First of all, let's make your tick asyncronous, to not block the current thread:

 public class TickMe
    {
        private int _counter;
        private object locker = new object();

        public async Task Run(CancellationToken cancelationToken)
        {
            _counter = 0;
            while (!cancelationToken.IsCancellationRequested)
            {
                await Task.Delay(200);
                Console.WriteLine("tik"   _counter);
                lock (locker)
                {
                    _counter  ;
                }
            }
        }
    }
  • Note the use of CancellationToken to stop the execution.
  • Note the use of lock to deal with the counter.

Then we create a CancellationToken to stop the execution of your asyncronous method, and pass it as parameter for the function on the main method and it's ready to go


public class Program
    {
        public static async Task Main(string[] args)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            var cancelationToken = source.Token;

            var tick = new TickMe();

            Task.Run(async () => await tick.Run(cancelationToken));

            await Task.Delay(1000);
            await Task.Delay(1000);

            Console.WriteLine("foo");

            await Task.Delay(1000);

            source.Cancel();

            await Task.Delay(1000);
            await Task.Delay(1000);

            Console.WriteLine("bar");
        }
    }

The results should be closer to this:

tik0
tik1
tik2
tik3
tik4
tik5
tik6
tik7
tik8
foo
tik9
tik10
tik11
tik12
tik13
bar
  • Related