C# 无法返回IObservable<;T>;来自标记为async的方法
这个人为设计的示例大致描述了我的代码的结构:C# 无法返回IObservable<;T>;来自标记为async的方法,c#,async-await,system.reactive,C#,Async Await,System.reactive,这个人为设计的示例大致描述了我的代码的结构: public abstract class SuperHeroBase { protected SuperHeroBase() { } public async Task<CrimeFightingResult> FightCrimeAsync() { var result = new CrimeFightingResult(); result.State = CrimeFigh
public abstract class SuperHeroBase
{
protected SuperHeroBase() { }
public async Task<CrimeFightingResult> FightCrimeAsync()
{
var result = new CrimeFightingResult();
result.State = CrimeFightingStates.Fighting;
try
{
await FightCrimeOverride(results);
}
catch
{
SetError(results);
}
if (result.State == CrimeFightingStates.Fighting)
result.State = CrimeFightingStates.GoodGuyWon;
return result;
}
protected SetError(CrimeFightingResult results)
{
result.State = CrimeFightingStates.BadGuyWon;
}
protected abstract Task FightCrimeOverride(CrimeFightingResult results);
}
public enum CrimeFightingStates
{
NotStarted,
Fighting,
GoodGuyWon, // success state
BadGuyWon // error state
}
public class CrimeFightingResult
{
internal class CrimeFightingResult() { }
public CrimeFightingStates State { get; internal set; }
}
我如何返回
ioobservable
并仍然等待调用FightCrimeAsync
?您可以将任务转换为可观察任务,并使用合并
将其合并:
public IObservable<CrimeFightingResult> AllHerosFightCrime()
{
var heros = new List<SuperHeroBase>(this);
return heros.Select(h => h.FightCrimeAsync().ToObservable())
.Merge();
}
公共IObservable AllHerosFightCrime()
{
var heros=新列表(此);
返回heros.Select(h=>h.FightCrimeAsync().ToObservable())
.Merge();
}
如果您想保持接收事件的顺序,您可以使用
Concat
而不是您所写的Merge
,我认为允许在第一个FightCrimeAsync
完成之前启动第二个FightCrimeAsync
。即使当前的Select
、ToObservable
和Merge
的实现使其按您想要的方式运行,这些函数的描述也允许其他行为。使用此代码运行一些更详细的测试后,@hvd是正确的。FightCrimeAsync任务可能会失去顺序。@mbursill-如果要保持顺序,请使用Concat
而不是Merge
。如果要这样做,可能需要延迟:“.Select(h=>Observable.Defer(()=>async h.FightCrimeAsync())”
public IObservable<CrimeFightingResult> AllHerosFightCrime()
{
var heros = new List<SuperHeroBase>(this);
return heros.Select(h => h.FightCrimeAsync().ToObservable())
.Merge();
}