异步 Disposable.Create

Async Disposable.Create

Disposable.Create 需要一个 Action 作为参数。当处理 Rx 订阅时,Action 是 运行。

在处理 Rx 订阅时,我想 运行 一些异步清理代码,但是使用 async () =>Actionasync void 相同,我想避开。有关我为什么要避免这种情况的更多详细信息,请参阅 here

是否可以创建类似 Disposable.AsyncCreate 的东西,它接受 Func<Task> 而不是 Action。如果是这样,我应该如何将其用作 CompositeDisposable 的一部分?

或者是否有其他模式来处理异步处置?

我认为 async () => 没有你认为的问题。

试试这个:

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();

它产生:

Hello
Wait
Goodbye

你可以这样做。我仍然不确定这个想法有多好:

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);
    }
}

然后您可以像这样使用它:

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");

}

此解决方案不适用于 using() 语句,class DisposableAsync 应该得到加强。除此之外,我想不出它有什么问题,但我倾向于(咳咳)反对它。只是感觉有点hacky。