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