问题描述
我的理解是,应避免async void
, 与Action
一起使用时,async () =>
只是伪装的async void
.
My understanding is that async void
, should be avoided and that async () =>
is just async void
in disguise when used with Action
.
因此,使用 Rx.NET最终运算符应避免与async () =>
异步进行,因为最终接受Action
作为参数:
Hence, using the Rx.NET Finally operator asynchronously with async () =>
should be avoided since Finally accepts Action
as parameter:
IObservable<T>.Finally(async () =>
{
await SomeCleanUpCodeAsync();
};
但是,如果这是不好的做法,那么如果我的观察对象是OnError或OnCompleted,那么在我需要异步关闭网络coOnCompleted的情况下,什么是最佳实践?
However, if this is bad practise, what is then best practice to use in the case where I need to asynchronously close a network coOnCompleted matter if my observable is OnError or OnCompleted?
推荐答案
这是部分错误的. async () =>
可以匹配Func<Task>
(良好)或Action
(不良).好的/不好的主要原因是async void
调用中发生的异常会使进程崩溃,而async Task
异常是可捕获的.
This is partially wrong. async () =>
can either match Func<Task>
(good) or Action
(bad). The main reason for good/bad is that an exception that occurs in a async void
call crashes the process, whereas a async Task
exception is catchable.
因此,我们只需要编写一个使用Func<Task>
而不是像Observable.Finally
这样的Action
的AsyncFinally
运算符:
So we just need to write an AsyncFinally
operator that takes in a Func<Task>
instead of an Action
like Observable.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
,则会使该过程崩溃.
If you swap out AsyncFinally
for Finally
, you'll crash the process.
这篇关于替代使用async()=>最终在Rx中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!