Background and motivation
Today it's not possible to use ChangeToken.OnChange to execute asynchronous logic before re-subscribing for new updates. The current API has an Action<T> based callback only. We need an async overload to run async logic so people don't end up using async void or blocking when using this helper.
API Proposal
namespace Microsoft.Extensions.Primitives;
public static class ChangeToken
{
// existing
// public static IDisposable OnChange(Func<IChangeToken?> changeTokenProducer, Action changeTokenConsumer);
// public static IDisposable OnChange<TState>(
// Func<IChangeToken?> changeTokenProducer, Action<TState> changeTokenConsumer, TState state);
public static IDisposable OnChange(Func<IChangeToken?> changeTokenProducer, Func<Task> changeTokenConsumer);
public static IDisposable OnChange<TState>(
Func<IChangeToken?> changeTokenProducer, Func<TState, Task> changeTokenConsumer, TState state);
}
API Usage
using Microsoft.Extensions.Primitives;
var config = new ConfigurationBuilder().AddJsonFile("config.json", optional: false, reloadOnChange: true)
.Build();
_ = ChangeToken.OnChange(config.GetReloadToken, async () =>
{
await Task.Delay(1000);
Console.WriteLine("Change happened");
});
Alternatives (added by @svick)
- Add a
CancellationToken parameter that's canceled when a following change is detected. This would probably be confusing, since not every caller would want to honor it and can be implemented by users if needed.
- Change the name to
OnAsyncChange (or similar). For those that use async lambda with OnChange today, this would be less breaking, but they wouldn't automatically get the benefit of the new version.
Risk (added by @svick)
This change means that existing code that uses an async lambda when calling OnChange will change meaning: previously, it compiled to an async void method; with this change, it will be an async Task method, where the callback is re-registered only once the returned Task completes. This could break some users, though the new behavior should be more correct.
Background and motivation
Today it's not possible to use
ChangeToken.OnChangeto execute asynchronous logic before re-subscribing for new updates. The current API has anAction<T>based callback only. We need an async overload to run async logic so people don't end up using async void or blocking when using this helper.API Proposal
API Usage
Alternatives (added by @svick)
CancellationTokenparameter that's canceled when a following change is detected. This would probably be confusing, since not every caller would want to honor it and can be implemented by users if needed.OnAsyncChange(or similar). For those that useasynclambda withOnChangetoday, this would be less breaking, but they wouldn't automatically get the benefit of the new version.Risk (added by @svick)
This change means that existing code that uses an
asynclambda when callingOnChangewill change meaning: previously, it compiled to anasync voidmethod; with this change, it will be anasync Taskmethod, where the callback is re-registered only once the returnedTaskcompletes. This could break some users, though the new behavior should be more correct.