You could do something like this. I'm still not sure how good the idea is:
public class DisposableAsync
{
private readonly IDisposable _disposable;
private readonly Func<Task> _asyncDisposalAction;
public DisposableAsync(IDisposable disposable, Func<Task> asyncDisposalAction)
{
_disposable = disposable;
_asyncDisposalAction = asyncDisposalAction;
}
public Task DisposeAsync()
{
_disposable.Dispose();
return _asyncDisposalAction();
}
}
public static class DisposableAsyncExtensions
{
public static DisposableAsync ToAsync(this IDisposable disposable, Func<Task> asyncDisposalAction)
{
return new DisposableAsync(disposable, asyncDisposalAction);
}
}
Then you can use it as follows:
async Task Go()
{
var o = Observable.Interval(TimeSpan.FromMilliseconds(100));
var d = o
.Subscribe(i => Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: {i}"))
.ToAsync(async () =>
{
Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Dispose Beginning");
await Task.Delay(1000);
Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Dispose Complete");
});
Console.Read();
var t = d.DisposeAsync();
Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Outside task, waiting for dispose to complete");
await t;
Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Task Complete");
}
This solution will not work with operators using(), and the class DisposableAsyncmust be extended. Beyond this, I cannot think of something wrong with this, but I am predisposed (s) against it. Just feels hacked.
source
share