Ожидание Rx наблюдаемого результата в контроллере никогда не приводит к какому-либо результату

#c# #.net #observable #system.reactive

#c# #.net #наблюдаемый #system.reactive

Вопрос:

У меня есть контроллер веб-API с методом POST, который я хочу использовать для обновления своих данных и их возврата. Мой сканер извлекает HTML, анализирует его и выдает значение в SourceObservable, содержащее проанализированные данные. Он работает нормально, когда Repository.Save(accreditationData) на самом деле сохраняется. Но возврат этого accreditationDataObservable не работает, поэтому мое действие никогда не завершает ответ, и Postman выглядит как ожидание на неопределенный срок:

 [HttpPost]
public async Task<AccreditationData<AllMantainedTableRow>> Post()
{
    var savedSubject = new Subject<bool>();

    AllMantainedCrawler.SourceObservable.Subscribe(accreditationData => {
        Repository.Save(accreditationData);
        savedSubject.OnNext(true);
    });

    var accreditationDataObservable = AllMantainedCrawler.SourceObservable.TakeUntil(savedSubject.AsObservable());

    AllMantainedCrawler.SourceSubject.OnNext(new Uri("my URL here"));

    return await accreditationDataObservable;
}
  

Также я попробовал Take(1) вместо TakeUntil этого, а также возвращался ToTask() вместо наблюдаемого, но получил тот же результат. Есть предложения?

Комментарии:

1. Почему вы используете наблюдаемый вместо задачи? влияет ли это на другие места?

2. У сканера есть это наблюдаемое, и это способ прослушивания свежих данных. Поэтому я хочу настроить подписку, запросить сканирование OnNext и вернуть первое значение, которое выдает наблюдаемое

Ответ №1:

AllMantainedCrawler.SourceSubject .onNext(новый Uri(«мой URL здесь»));

Эта строка заставляет искатель выдавать. Поэтому savedSubject он также будет излучать.

var accreditationDataObservable = AllMantainedCrawler .SourceObservable.takeUntil(сохраненный объект.asObservable());

если saveSubject выдает приведенную выше строку, завершите accreditationDataObservable , но в последней строке вы пытаетесь дождаться уже завершенного accreditationDataObservable .

если вы удалите строку onNext и разрешите искателю выдавать, вы можете ожидать accreditationDataObservable до тех пор, пока он не завершится.

Ответ №2:

Никогда не вызывайте OnNext внутри a Subscribe . Всегда есть способ избежать этого.

С вашим кодом кажется, что это было бы эквивалентно без OnNext :

 public async Task<AccreditationData<AllMantainedTableRow>> Post()
{
    var accreditationDataObservable = AllMantainedCrawler.SourceObservable.Take(1).Do(x => Repository.Save(x));
    AllMantainedCrawler.SourceSubject.OnNext(new Uri("my URL here"));
    return await accreditationDataObservable;
}
  

Однако я не могу понять, что AllMantainedCrawler.SourceSubject.OnNext(new Uri("my URL here")); здесь делает, поскольку вы не предоставили достаточно подробностей в вопросе. Если вы можете предоставить полный код, я думаю, что смогу вам помочь.


Как уже упоминалось, я не знаю, как SourceSubject это связано с SourceObservable , но если я могу предположить, что accreditationData это только Uri то, что это сработает:

 public async Task<AccreditationData<AllMantainedTableRow>> Post()
{
    return await Observable.Start(() => Repository.Save(new Uri("my URL here")));
}