异步一次性创建

Jas*_*sen 5 c# dispose asynchronous system.reactive async-await

Disposable.Create需要一个Actionas参数。的Action与Rx订阅被设置时被运行。

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

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

还是有其他用于处理异步处置的模式?

Shl*_*omo 3

你可以做这样的事情。我仍然不确定这个主意有多好:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

}
Run Code Online (Sandbox Code Playgroud)

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