I have a class which spawns various tasks which can run indefinitely. When this object is disposed, I want to stop those tasks from running.
Is this the correct approach:
public class MyClass : IDisposable
{
// Stuff
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
queueCancellationTokenSource.Cancel();
feedCancellationTokenSource.Cancel();
}
}
}
You're on the right track. However, I would suggest waiting for the task to terminate before returning from the Dispose
method, in order to avoid race conditions where the task continues to operate after the object has been disposed. Also dispose the CancellationTokenSource
.
Update: If you're on .NET Core 3.0 or later, you should make your class implement IAsyncDisposable
and await your task from the DisposeAsyncCore
method. I've updated the example below to reflect this.
using System;
using System.Threading;
using System.Threading.Tasks;
public class MyClass : IDisposable, IAsyncDisposable
{
private readonly CancellationTokenSource feedCancellationTokenSource =
new CancellationTokenSource();
private readonly Task feedTask;
public MyClass()
{
feedTask = Task.Factory.StartNew(() =>
{
while (!feedCancellationTokenSource.IsCancellationRequested)
{
// do finite work
}
});
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
feedCancellationTokenSource.Cancel();
feedTask.Wait();
feedCancellationTokenSource.Dispose();
feedTask.Dispose();
}
}
public async ValueTask DisposeAsync()
{
await DisposeAsyncCore().ConfigureAwait(false);
Dispose(false);
GC.SuppressFinalize(this);
}
protected virtual async ValueTask DisposeAsyncCore()
{
feedCancellationTokenSource.Cancel();
await feedTask.ConfigureAwait(false);
feedCancellationTokenSource.Dispose();
feedTask.Dispose();
}
}
// Sample usage:
public static class Program
{
public static async Task Main()
{
await using (new MyClass())
{
// do something else
}
Console.WriteLine("Done");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With