I want to call a function in a different thread than my GUI.
I used the below code to trigger the function:
private void button1_Click(object sender, EventArgs e)
{
tokensource = new CancellationTokenSource();
var token = tokensource.Token;
Task.Run(()=>foo() , token);
}
private void foo()
{
// Uses some resources
}
private void button2_Click(object sender, EventArgs e)
{
tokenSource.Cancel();
}
How can I safely close the occupied resources in foo()
when the task is cancelled?
You need to pass the token to the function as well. The cancellation token passed to Task.Run won't abort an already running task, it will prevent a scheduled task from running.
Inside foo
, you can check the token for cancellation and return, or throw an exception. You can use a using
block to dispose resources safely. Eg:
private void foo(CancellationToken token)
{
using(var reader=new StreamReader(somePath)
{
string line;
// Read the line if no cancellation was requested
while (!token.IsCancellationRequested && (line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
This code reads a line only if cancellation wasn't requested and returns quietly otherwise
You can also throw an OperationCancelledException by calling CancellationToken.ThrowIfCancellationRequested
private void foo(CancellationToken token)
{
using(var reader=new StreamReader(somePath)
{
string line;
// Read the line if no cancellation was requested
while ((line = sr.ReadLine()) != null)
{
token.ThrowIfCancellationRequested();
Console.WriteLine(line);
}
}
}
This will throw an exception that will be raised in the calling code when the task's result is retrieved, eg when using await Task.Run(..)
or Task.Run(..).Wait()