在最终处方中使用async()=>的替代方法 [英] Alternative to using async () => in Rx Finally

查看:0
本文介绍了在最终处方中使用async()=>的替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的理解是async voidshould be avoidedasync () => Action一起使用时,只是变相的async void

因此,应避免使用the Rx.NET Finally operatorasync () => 异步,因为最终接受Action作为参数:

IObservable<T>.Finally(async () =>
{
    await SomeCleanUpCodeAsync();
};

但是,如果这是不好的做法,那么在例如我需要异步关闭OnComplete上的网络连接或者如果我的可观察到的结尾是OnError的情况下,使用什么是最佳做法?

推荐答案

我的理解是,应该避免异步无效,async () =>只是async void的伪装。

这是部分错误的。async () =>可以匹配Func<Task>(好)或Action(坏)。好/坏的主要原因是,async void调用中发生的异常会导致进程崩溃,而async Task异常是可捕获的。

所以我们只需要编写一个AsyncFinally运算符,它接受Func<Task>而不是ActionLikeObservable.Finally

public static class X
{
    public static IObservable<T> AsyncFinally<T>(this IObservable<T> source, Func<Task> action)
    {
        return source
            .Materialize()
            .SelectMany(async n =>
            {
                switch (n.Kind)
                {
                    case NotificationKind.OnCompleted:
                    case NotificationKind.OnError:
                        await action();
                        return n;
                    case NotificationKind.OnNext:
                        return n;
                    default:
                        throw new NotImplementedException();
                }
            })
            .Dematerialize()
        ;
    }
}

这里有一个用法演示:

try
{
    Observable.Interval(TimeSpan.FromMilliseconds(100))
        .Take(10)
        .AsyncFinally(async () =>
        {
            await Task.Delay(1000);
            throw new NotImplementedException();
        })
        .Subscribe(i => Console.WriteLine(i));
}
catch(Exception e)
{
    Console.WriteLine("Exception caught, no problem");
}

如果将AsyncFinally换成Finally,将导致进程崩溃。

这篇关于在最终处方中使用async()=&amp;gt;的替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆