c# – 当我用linq键入时运行任务(如果仍在运行则取消上一个任务)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 当我用linq键入时运行任务(如果仍在运行则取消上一个任务),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2900字,纯文字阅读大概需要5分钟。
内容图文
![c# – 当我用linq键入时运行任务(如果仍在运行则取消上一个任务)](/upload/InfoBanner/zyjiaocheng/771/5832331672bc43febbcf140c427722c9.jpg)
我想创建一个在我键入时使用linq搜索的任务,如果用户键入另一个字符,它应该取消任务并重新创建搜索,我有以下代码:
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
}
我得到这个例外:
类型’System.OperationCanceledException’的例外
发生在System.Core.dll中但未在用户代码中处理
附加信息:操作已取消.
我是一个有任务和取消的初学者,可以从这里指导我正确的路径吗?我基本上希望Task检查它是否已经运行,取消它,然后使用新值再次运行它(我想使这个“SearchBox”功能类似于visual studio在解决方案资源管理器中的搜索,在您键入时搜索)
解决方法:
首先,您需要创建一个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,它将在处理时被取消.
选择(x => …).Switch()仅获取最新的查询结果,并处理最后一个查询.
ObserveOn(…)在使用的调度程序上运行以下命令,确保在使用WPF时使用DispatchScheduler,如果使用Winforms则使用WinformsScheduler.
订阅(结果=> …)对结果做一些事情.
内容总结
以上是互联网集市为您收集整理的c# – 当我用linq键入时运行任务(如果仍在运行则取消上一个任务)全部内容,希望文章能够帮你解决c# – 当我用linq键入时运行任务(如果仍在运行则取消上一个任务)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。