在最终处方中使用async()=&;gt;的替代方法 [英] Alternative to using async () => in Rx Finally
本文介绍了在最终处方中使用async()=&;gt;的替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我的理解是async void
,should be avoided,async () =>
和Action
一起使用时,只是变相的async void
。
因此,应避免使用the Rx.NET Finally operator与async () =>
异步,因为最终接受Action
作为参数:
IObservable<T>.Finally(async () =>
{
await SomeCleanUpCodeAsync();
};
但是,如果这是不好的做法,那么在例如我需要异步关闭OnComplete上的网络连接或者如果我的可观察到的结尾是OnError的情况下,使用什么是最佳做法?
推荐答案
我的理解是,应该避免异步无效,
async () =>
只是async void
的伪装。
这是部分错误的。async () =>
可以匹配Func<Task>
(好)或Action
(坏)。好/坏的主要原因是,async void
调用中发生的异常会导致进程崩溃,而async Task
异常是可捕获的。
所以我们只需要编写一个AsyncFinally
运算符,它接受Func<Task>
而不是Action
LikeObservable.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()=&;gt;的替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文