Создать IObservable из метода и других

Правильно ли написан код ниже для возврата IObservable с точки зрения библиотеки Rx? Кажется, это работает правильно, но интересно, я использую это правильно.

private IObservable<SearchResult[]> Search(string query)
{
    return Observable.Create((IObserver<SearchResult[]> observer)=>
        {
            List<SearchResult> result = new List<SearchResult>();
            foreach (TestsGroupMeta group in Engine.Groups)
            {
                string name = group.ToString();
                if (name.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) != -1)
                {
                    result.Add(new SearchResult{ Name = name, Type = "Group"});
                }

                foreach (TestMethodMeta method in group.Methods)
                {
                    name = method.ToString();
                    if (name.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) != -1)
                    {
                        result.Add(new SearchResult {Name = name, Type = "Method"});
                    }
                }
            }

            observer.OnNext(result.ToArray());
            observer.OnCompleted();

            return () => {};
        });
}

Использование так.

private void SearchForm_Load(object sender, EventArgs e)
{
    var textChanged = Observable.FromEventPattern<EventArgs>(txtQuery, "TextChanged")
        .Select(_ => ((TextBox)_.Sender).Text);

    var searchResult = from query in textChanged
        where query.Length >= 3
        from result in Search(query)
        select result;

    _resultsWatcher = searchResult
        .Throttle(TimeSpan.FromMilliseconds(200))
        .ObserveOn(lvResults)
        .Subscribe(resuts =>
            {
                lvResults.BeginUpdate();
                lvResults.Items.Clear();
                foreach (SearchResult result in resuts)
                {
                    ListViewItem item = new ListViewItem(result.Name);
                    item.SubItems.Add(result.Type);
                    lvResults.Items.Add(item);
                }

                lvResults.EndUpdate();
            });
}

Кроме того, есть ли способ создать IObservable из такого метода?

Task<List<SearchResult>> Search(string query){...}

Или, каковы другие подходы для создания асинхронного поиска по большому набору данных и получения IObservable из него.

Спасибо

1 ответ

Решение

Вы можете создать наблюдаемую из задачи как таковой,

Task<List<SearchResult>> SearchAsync(string query){...}

var observable = Observable.FromAsync<List<SearchResult>>(()=> SearchAsync(query));

Если ваша функция возвращает только 1 результат в будущем, подумайте об использовании Task вместо этого?

public async Task<SearchResult[]> SearchAsync(string query){ }
Другие вопросы по тегам