Async Disposable.Create

Disposable.Create requires the Actionas parameter . Actionstarts when an Rx subscription is placed.

When disposing of an Rx subscription identifier, for example, to run some asynchronous cleansing code, however, using async () =>with is Actionidentical async voidwhich identifier should be avoided. See here for more on why I want to avoid this .

Is it possible to create something Disposable.AsyncCreatethat accepts Func<Task>, and not Action. If so, how should I use it as part CompositeDisposable?

Or are there other patterns for working with asynchronous deletion?

+4
source share
2 answers

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.

+3
source

I don’t think async () =>there are problems you are thinking about.

Try the following:

Action x = async () =>
{
    try
    {
        Console.WriteLine("Hello");
        await Task.Delay(TimeSpan.FromSeconds(2.0));
        throw new Exception("Wait");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    Console.WriteLine("Goodbye");
};

var d = Disposable.Create(x);

d.Dispose();

It produces:

Hello
Wait
Goodbye
+1
source

Source: https://habr.com/ru/post/1682143/


All Articles