Memory leak due to undetached events inside BackgroundService - c#

I have a memory leak caused by the code below, probably due to undetached events, and I don't know how to properly unsubscribe from them.
I have the interface IEventsHandler, declared as singleton, which exposes some events. This interface is used inside a BackgroundService, where a subscriber is attached to the event. When an AlertEvent occurs, a scope is created to use a service which stores the event inside the database.
Here is the code:
public class MyWorker : BackgroundService
{
private readonly IEventsHandler _eventsHandler;
private readonly IServiceProvider _serviceProvider;
public MyWorker(IEventsHandler eventsHandler,
IServiceProvider serviceProvider)
{
_eventsHandler = eventsHandler;
_serviceProvider = serviceProvider;
_eventsHandler.AlertOccurred += AlertEventOccurred;
}
private async void AlertEventOccurred(object sender, AlertEvent e)
{
using var scope = _serviceProvider.CreateScope();
var service = scope.ServiceProvider.GetRequiredService<AlertService>();
await service.SaveAlert(e);
}
}
public interface IEventsHandler
{
event EventHandler<AlertEvent> AlertOccurred;
Task AddAlertEventAsync(AlertEvent ev);
}
public class EventsHandler : IEventsHandler
{
public event EventHandler<AlertEvent> AlertOccurred;
public async Task AddAlertEventAsync(AlertEvent ev)
{
await Task.Run(() => AlertOccurred?.Invoke(this, ev));
}
}
PS any advice on bad practices used in the example code is welcome :-)
Thanks

BackgroundService implements IHostedService interface which has a couple of methods named StartAsync and StopAsync.
It's better to use these methods instead of class constructor to subscribe to your events and then unsubscribe from them.
This way
public override Task StartAsync(CancellationToken cancellationToken)
{
_eventsHandler.AlertOccurred += AlertEventOccurred;
return Task.CompletedTask;
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_eventsHandler.AlertOccurred -= AlertEventOccurred;
return Task.CompletedTask;
}

If this is actually the cause of your memory leak, the fix is pretty simple. Just create a destructor and unsubscribe from the event.
A destructor is the opposite of a constructor in that it gets called right before the object gets garbage collected. It's denoted by a tilde (~) preceding the same syntax as a constructor (minus the parameters). Yours would look something like this:
~MyWorker(){
_eventsHandler.AlertOccurred -= AlertEventOccurred;
}

Related

Implementing both IDisposable and IAsyncDisposable

Say I have a non-sealed class that does not deal with any unmanaged resources. I need to make a single async call during its disposing stage to do some clean up. There are no other managed resources to deal with.
From what I understand, in order to make the async clean up call, I must implement IAsyncDisposable and use the DisposeAsync() and DisposeAsyncCore() methods. But the guidance says that you should also implement the dispose pattern when you implement the async dispose pattern. This is all fine but there's nothing really I need to do in the Dispose().
So my question is, should the Dispose() logic be empty or do I need something to do the async cleanup in a synchronous way? (see comment in code about "What if anything should go here").
public class MyClass : IDisposable, IAsyncDisposable
{
private bool disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public async ValueTask DisposeAsync()
{
await DisposeAsyncCore().ConfigureAwait(false);
Dispose(false);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// What if anything should go here?
}
disposed = true;
}
}
protected virtual async ValueTask DisposeAsyncCore()
{
// Make async cleanup call here e.g. Database.CleanupAsync();
}
}
Example to those who still hesitate to implement both:
internal class Program
{
static void Main(string[] args)
{
foreach (var a in new B()){}
//IAsyncDisposable is not called - you leaking resources.
//No deadlocks in UI, no warning in compilation, nothing.
//So it is better to be on safe side and implement both
//because you never know how one will manage lifetime of your class.
}
public class B : IEnumerable, IAsyncEnumerable<object>
{
public IEnumerator GetEnumerator() => new A();
public IAsyncEnumerator<object> GetAsyncEnumerator(CancellationToken ct) => new A();
}
public class A : IAsyncEnumerator<object>, IEnumerator
{
public ValueTask DisposeAsync()
{
Console.WriteLine("Async Disposed");
return ValueTask.CompletedTask;
}
public bool MoveNext() => false;
public void Reset(){}
public ValueTask<bool> MoveNextAsync() => ValueTask.FromResult(false);
public object Current => null;
}
}
Conclusion
You can freely add support for async version only, but beware: some wraps, like foreach or older versions of DI containers (Ninject, StructureMap, etc), code generators like RestSharp, or proxy generators like Castle.Proxy might not support IAsyncDisposable. Failing to cast object to IDisposable will present hard to catch bugs in your app. Whereas if you do implement it, the worst thing that could happen is deadlock in finally block (if you do it through sync-over-async).
In general, it is better to support both operations if you plan to make it public API or you don't have control over your class lifetime (like in DI containers or other widely known wrappers).
How to
There is full Microsoft example on how to implement both of them in inheritable class (non-sealed, like in your example) - https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync#implement-both-dispose-and-async-dispose-patterns
class ExampleConjunctiveDisposableusing : IDisposable, IAsyncDisposable
{
IDisposable? _disposableResource = new MemoryStream();
IAsyncDisposable? _asyncDisposableResource = new MemoryStream();
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
public async ValueTask DisposeAsync()
{
await DisposeAsyncCore().ConfigureAwait(false);
Dispose(disposing: false);
#pragma warning disable CA1816 // Dispose methods should call SuppressFinalize
GC.SuppressFinalize(this);
#pragma warning restore CA1816 // Dispose methods should call SuppressFinalize
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_disposableResource?.Dispose();
(_asyncDisposableResource as IDisposable)?.Dispose();
_disposableResource = null;
_asyncDisposableResource = null;
}
}
protected virtual async ValueTask DisposeAsyncCore()
{
if (_asyncDisposableResource is not null)
{
await _asyncDisposableResource.DisposeAsync().ConfigureAwait(false);
}
if (_disposableResource is IAsyncDisposable disposable)
{
await disposable.DisposeAsync().ConfigureAwait(false);
}
else
{
_disposableResource?.Dispose();
}
_asyncDisposableResource = null;
_disposableResource = null;
}
}
Both implementations of dispose feature is from the callers point of view. Your class would then offer both mechanisms to dispose off any managed and unmanaged resources and the caller application decides what to choose. This also ensures that any consumer which is unable to make use of asynchronous patterns are not lost.
You do not really need to implement synchronous dispose if you are sure about or want to force asynchronous consumption of your class.
So depending on your vision of class usage, you can choose how to dispose objects. If you choose to keep both mechanisms, you can dispose all resources both ways.
As you have said, the class is non-sealed. For sealed classes, it's enough to implement I(Async)Disposable interface. The Disposable pattern exists because the derived class may want to add cleanup logic that can be either sync or async. You can't know. That's why you need to implement the whole pattern for sync and async cases.
For your question. Never block async call in sync Dispose method. It's a caller's responsibility to use your class correctly. If he decides to call Dispose instead of DisposeAsync and clear only sync resources it's his decision/mistake. If this async call in DisposeAsync is absolutely necessary for proper cleanup and it is controlled by you, consider adding sync equivalent to be used in Dispose method.

How to inject a fake implementation of a class providing no interface and no virtual methods?

I'm using the Discord.Net package offering me the DiscordSocketClient class, which currently is a Singleton in my DI container. I need several methods from the instance
Task LoginAsync(TokenType tokenType, string token, bool validateToken = true)
Task StartAsync()
Task LogoutAsync()
Task StopAsync()
Given this example class consuming the methods
public sealed class ConsumingClass
{
private readonly DiscordSocketClient _discordSocketClient;
public ConsumingClass(DiscordSocketClient discordSocketClient)
{
_discordSocketClient = discordSocketClient;
}
public override async Task Initialize(CancellationToken cancellationToken)
{
await _discordSocketClient.LoginAsync(TokenType.Bot, "my-token");
await _discordSocketClient.StartAsync();
}
public override async Task TearDown(CancellationToken cancellationToken)
{
await _discordSocketClient.LogoutAsync();
await _discordSocketClient.StopAsync();
}
}
I want to create tests using XUnit and Moq to ensure the instance of ConsumingClass works as expected.
Unfortunately DiscordSocketClient does not offer an interface so I can't inject a mock implementation to my tests.
Also the methods are not virtual, so it is not possible to create an instance of Mock<DiscordSocketClient> and use .Setup() to setup mock implementations.
So how can I verify in my testcase, that the client methods have been called once? E.g. _discordSocketClientMock.Verify(discordSocketClient => discordSocketClient.LoginAsync(), Times.Once());
Do I have to create an interface IMyDiscordSocketClient providing those methods and a class another class MyDiscordSocketClient inheriting from DiscordSocketClient and implementing the interface and use that? Or are there any better ways?
If DiscordSocketClient does not have (public) virtual members, you cannot really derive from it either. Your last suggestion is however probably still the best possibility you have, except that MyDiscordSocketClient should not derive from DiscordSocketClient, but aggregate one.
public class MyDiscordSocketClient: IMyDiscordSocketClient
{
private DiscordSocketClient _client;
public MyDiscordSocketClient(DiscordSocketClient client)
{
_client = _client;
}
public async Task Initialize(CancellationToken cancellationToken)
{
_client.Initialize(cancellationToken);
}
// etc...
}

Simple Injector dynamic context-based injection at runtime between two registrations

I have a Mediator application using Simple Injector for command handler registration, and injection and handlers is all setup and working perfectly.
class DoWashingCommandHandler : IRequestHandler<DoWashingCommand,object>
{
IBus bus;
public DoWashingCommandHandler(IBus bus) { this.bus = bus; }
Task<object> Handle(DoWashingCommand command)
{
this.bus.Send(new OtheCommand());
}
}
I have a need for 2 registrations of a IBus implementations.
The first can be of any lifetime, the second has a background thread so i initially thought it would need to be a singleton but on review i believe it could also be of any lifetime and just have a static worker thread class within it (this would be important for scope):
// register as non-singleton to allow scope usage
// keep static worker thread as if it were Singleton
class DispatchOnBackgroundThread : IBus
{
static Worker = new Worker();
public Task<object> Send(object command)
{
Worker.Post(command);
}
public void Start(Container container, CancelationToken stoppingToken)
{
Worker.Start(container,stoppingToken);
}
class Worker
{
public void Post(object command) { /* snip */ }
public void Start(Container container, CancelationToken stoppingToken)
{ /* snip */ }
public void Thread()
{
/* loop */
var item = ReadFromQueue();
// get command handler type
// get command handler instance from container
// if instantiated instance has IBus dependency in this
// section then it must have used DispatchInThread as the
// concrete implementation for IBus (including if the handler
// calls container.GetInstance<IBus>()
handler.Handle(item.Request, cancellationToken);
}
// anything outside this Thread should use
// DispatchOnBackgroundThread for IBus
}
}
Then the registrations would be as follows (not sure how to avoid the double registration issue of IBus):
// i need to be able to register two types
container.Register<IBus,DispatchOnBackgroundThread>();
container.Register<IBus,DispatchInThread>();
// this would return any IBus references with DispatchOnBackgroundThread
var handler = this.container.GetInstance(requestHandlerType);
using(SomeSope.BeingScope(container))
{
// this would return any IBus references with DispatchInThread
var handler = this.container.GetInstance(requestHandlerType);
// and if handler or other code referenced container and called
// GetInstance, and IBus dependencies would be returned as
// DispatchInThread whilst in this scope
}
// this would return any IBus references with DispatchOnBackgroundThread
var other = this.container.GetInstance(requestHandlerType);
I think and in summary, this is a mix of Context-based injection and custom scope.
How can I achieve the above or is this a terrible code smell?
To give further context if required I need the above switchable resolved types in order to implement the solution of another question https://stackoverflow.com/a/61782405/915839
DI code is removed in above link, but i am very much using SimpleInjector in the actual implementation
I'm not sure I fully understand your use case, and what it is that leads to this, but what you can do is create a wrapper IBus implementation that forwards the call to the correct bus, while changing the forwarded bus implementation while running on a background thread.
This wrapper might look as follows:
class SwitchableBus : IBus
{
private readonly DispatchInCallingThread defaultBus;
private readonly DispatchOnBackgroundThread backgroundBus;
public SwitchableBus(
DispatchInCallingThread defaultBus, DispatchOnBackgroundThread backgroundBus)
{
this.defaultBus = defaultBus;
this.backgroundBus = backgroundBus;
this.Bus = defaultBus;
}
public IBus Bus { get; private set; }
public void SwitchToBackgroundBus() => this.Bus = this.backgroundBus;
public Task<object> Send(object command) => this.Bus.Send(command);
}
With this wrapper, you can use the following registrations:
container.Register<IBus, SwitchableBus>(Lifestyle.Scoped);
container.Register<SwitchableBus>(Lifestyle.Scoped);
container.Register<DispatchInCallingThread>(Lifestyle.Scoped);
container.Register<DispatchOnBackgroundThread>(Lifestyle.Scoped);
This allows you to have DispatchInCallingThread used in the graph as follows:
using(SomeSope.BeingScope(container))
{
var handler = this.container.GetInstance(requestHandlerType);
handler.Handle(request);
}
In other words, by default the DispatchInCallingThread is used.
And DispatchOnBackgroundThread can be used by the graph as follows:
using(SomeSope.BeingScope(container))
{
container.GetInstance<SwitchableBus>().SwitchToBackgroundBus();
var handler = this.container.GetInstance(requestHandlerType);
handler.Handle(request);
}
Concequence of this is, however, that you should always resolve within an active Scope. But that would be a good idea anyway, because it is likely there will be Scoped dependencies in a graph anyway. Simple Injector does not allow resolving a graph with Scoped dependencies outside the context of an active scope.

IAsyncDisposable, IDisposable to dispose internal IAsyncDisposable member in a base class

I am working with asp.net core signalR. I made a HubClientBase (which is a client for communicating with the signalR hub/server). It uses an HubConnection object to send/receive data in the derived classes.
public abstract class HubClientBase : IDisposable, IAsyncDisposable
{
#region Properties and fields
protected readonly ILogger<HubClientBase> Logger;
protected readonly HubConnection Connection;
#endregion
...
// Start connection
// Some other stuff
}
// Derived:
public class AlarmHubClient : HubClientBase, IAlarmHubClient, IAlarmHub
{
/// <inheritdoc />
public AlarmHubClient(ILogger<HubClientBase> logger, HubConnection connection)
: base(logger, connection)
{
}
protected override void AttachReceiveHandlers(HubConnection connection)
{
connection.On<AlarmBarMessageDto>(nameof(ReceiveCurrentAlarmBarMessage), ReceiveCurrentAlarmBarMessage);
...
}
#region Implementation of IAlarmHubClient
/// <inheritdoc />
public async Task SendCurrentAlarmBarMessage(AlarmBarMessageDto alarmBarMessage)
{
await Connection.SendAsync(nameof(SendCurrentAlarmBarMessage), alarmBarMessage);
}
I run into 2 problems pertaining disposale however.
I use the client in a .NET 4.6.1 project. The dll gets loaded into a WPF application. This means, that .Dispose() is called by the UI thread. The hubconnection only has a .DisposeAsync implementation, so i need to call that from the .Dispose method. We follow a hierachical dispose pattern, so i need to be sure the dispose is blocking until it is done. I however cannot Wait() in the dispose, since that would block the ui thread (a deadlock occurs, where the task will be scheduled to run on the main ui thread, but the thread cannot do any work because its waiting)
This means, I have to use Task.Run - which is far from an ideal solution...
#region IDisposable
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (Connection != null)
{
// Force the async method on the thread pool with Task.Run.
// WARN A library / base should 99.9% of the time never use Task.Run, since the creation of threads should be a responsibility of the application level.
Task.Run(async () => await Connection.DisposeAsync())
.ConfigureAwait(true).GetAwaiter().GetResult();
}
}
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
What would be a better way to go about Async disposing a member in the sync dispose?
I tried using IAsyncDisposable aswell, so I can maybe work some magic upstream and use that instead of Dispose(). I came up with the following, but i found ample documentation about how to correctly use IAsyncDispose. especially since this is a baseclass that will be derived from:
#region Implementation of IAsyncDisposable
/// <inheritdoc />
public ValueTask DisposeAsync()
{
try
{
return new ValueTask(Connection.DisposeAsync());
}
catch (Exception exc)
{
return new ValueTask(Task.FromException(exc));
}
}
#endregion
Is this a good way of async dispoing a member in the async dispose? Any recommendations for derived classes?

"Dispose is cancel" sementic on C# Tasks

I wanted to have a Task implementation that whenever it is get disposed, the task associated is canceled. So I have the following naive implementation in mind
public class AutoCancelTask : Task, IDisposable
{
public static AutoCancelTask Create(Action<CancellationToken> a)
{
return new AutoCancelTask(a, new CancellationTokenSource());
}
private CancellationTokenSource cts;
internal AutoCancelTask(Action<CancellationToken> a, CancellationTokenSource cts)
:base((() => a(cts.Token)))
{ this.cts = cts; }
void IDisposable.Dispose(){
cts.Cancel();
Dispose();
}
}
To simplify I only consider the simplest Task constructor. Adding other constructors would not be hard anyway.
My concern is how the IDisposable interface is being implemented. Since Task also implements IDisposable, would the above code cause any problems in certain scenarios? More importantly, would the above code do the right thing?

Categories

Resources