代码之家  ›  专栏  ›  技术社区  ›  1iveowl Diego Sanchez

异步一次性创建

  •  6
  • 1iveowl Diego Sanchez  · 技术社区  · 7 年前

    Disposable.Create 需要 Action 作为参数。这个 在处理Rx订阅时运行。

    在处理Rx订阅Id时,希望运行一些异步清理代码,但是使用 async () => 具有 行动 与相同 async void here .

    有没有可能创造出像 Disposable.AsyncCreate ,它接受 Func<Task> 行动 .如果是这样,我应该如何使用它作为 CompositeDisposable ?

    2 回复  |  直到 7 年前
        1
  •  3
  •   Shlomo    7 年前

    你可以这样做。我仍然不确定这是一个多么好的主意:

    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() 语句和类 DisposableAsync

        2
  •  0
  •   Enigmativity    7 年前

    我不认为 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