Run Task when entering from linq (undo the previous task, if still running)

I want to make a task that searches with linq as it types, and if the user enters another character, he must cancel the task and recreate the search, I have the following code:

private Task SearchChannels;
private CancellationTokenSource cancelSearch;

public void PopulateChannels(string newValue)
{
    IsSearchingChannels = true; //This just shows a progressbar
    if (SearchChannels != null && cancelSearch!= null)
        if (SearchChannels.Status == TaskStatus.Running || 
            SearchChannels.Status == TaskStatus.WaitingToRun || 
            SearchChannels.Status == TaskStatus.WaitingForActivation || 
            SearchChannels.Status == TaskStatus.WaitingForChildrenToComplete) 
        {
            cancelSearch.Cancel();
            SearchChannels.Wait();
        }
    cancelSearch = new CancellationTokenSource();
    SearchChannels = new Task(() => Channels = new PagedObservableCollection<Channel>(ContractManager.Channels.Where(x => x.Name.ToLower().StartsWith(newValue)).AsParallel().WithCancellation(cancelSearch.Token).ToList()), cancelSearch.Token); //PagedObservableCollection is just a simple class with a list that keeps all items and an ObservableCollection for current items shown

    SearchChannels.Start();
    SearchChannels.ContinueWith((continuation) => IsSearchingChannels = false); // this just hides the progressbar when done
}

I get this exception:

A type exception 'System.OperationCanceledException' occurred in System.Core.dllbut was not handled in the user code

Additional Information: The operation has been canceled.

I'm starting out a bit with tasks and canceling Tokens, can someone lead me on the right path from here? I basically want the task to check whether it is running, cancel it and start it again with a new value (I want this SearchBox function to look like a visual studio search engine in the solution browser that does a type search)

+4
1

-, IObservable<string>, . " " Subject<string>, , , .

, ViewModel.

IDisposable _searchSubscriber =
    _searchString
         .Buffer(TimeSpan.FromMillisecond(300))
         .Select(searchString => 
                Observable.StartAsync(cancelToken => 
                      Search(searchString, cancelToken)
                ).Switch()
         .ObserveOn(new DispatcherScheduler())
         .Subscribe(results => Channels = results);

public Task<List<Channel>> Search(string searchTerm, CancellationToken cancel)
{
    var query = dbContext.Channels.Where(x => x.Name.StartsWith(searchTerm));
    return query.ToListAsync(cancel);
}

private BehaviorSubject<string> _searchString = new BehaviorSubject<string>("");
public string SearchString
{
    get { return _searchString.Value; }
    set { _searchString.OnNext(value); OnPropertyChanged("SearchString"); }
}

Rx.net - , , , , ( , , ).

...

.Buffer(TimeSpan.FromMilliseconds(300)) , 300 .

Observable.StartAsync(cancelToken => Search(searchString, cancelToken)) Observable , , .

Select(x => ...).Switch() .

ObserveOn(...) , , DispatchScheduler, WPF, WinformsScheduler, Winforms.

Subscribe(results => ...) - .

+1

All Articles