鉴于以下方法观察到:非折返在C#
如果我离开了黑客到位,我的单元测试立即“可观察有没有数据”完成。
如果我采取了破解,有多个线程都尝试在同一时间登录。
主机服务不允许此。
如何确保只有一个线程是生产在任何给定时间点观测。
private static object obj = new object();
private static bool here = true;
public IObservable<Party> LoadAllParties(CancellationToken token)
{
var parties = Observable.Create<Party>(
async (observer, cancel) =>
{
// this is just a hack to test behavior
lock (obj)
{
if (!here)
return;
here = false;
}
// end of hack.
try
{
if (!await this.RequestLogin(observer, cancel))
return;
// request list.
await this._request.GetAsync(this._configuration.Url.RequestList);
if (this.IsCancelled(observer, cancel))
return;
while (!cancel.IsCancellationRequested)
{
var entities = await this._request.GetAsync(this._configuration.Url.ProcessList);
if (this.IsCancelled(observer, cancel))
return;
var tranche = this.ExtractParties(entities);
// break out if it's the last page.
if (!tranche.Any())
break;
Array.ForEach(tranche, observer.OnNext);
await this._request.GetAsync(this._configuration.Url.ProceedList);
if (this.IsCancelled(observer, cancel))
return;
}
observer.OnCompleted();
}
catch (Exception ex)
{
observer.OnError(ex);
}
});
return parties;
}
我的单元测试:
var sut = container.Resolve<SyncDataManager>();
var count = 0;
var token = new CancellationTokenSource();
var observable = sut.LoadAllParties(token.Token);
observable.Subscribe(party => count++);
await observable.ToTask(token.Token);
count.Should().BeGreaterThan(0);
我看到一个'Observable.Create'调用,一个锁,以及一大堆无法解释的不可编译的自定义代码。如果你能产生[mcve],那可能会有所帮助。 – Shlomo
我可以尝试做一个更简单的例子 - 但问题仍然是锁被多个线程击中。为什么?很明显,可观察性如何工作......我需要使其不可重入。我会努力简化这个例子。您可以用await Task.Delay(1000) – Jim
替换每个异步调用您的客户端代码可能导致该问题。你对创建的可观测物体做了什么? – Shlomo