注意:取决于this quetion
您好。我有一个像这样的视图模型:
public class ViewModel {
private readonly IPersonService _personService;
private readonly ObservableCollection<SearchPersonModel> _foundedList;
private readonly DispatcherTimer _timer;
private readonly Dispatcher _dispatcher;
private CancellationTokenSource _tokenSource;
public SearchPatientViewModel(IPersonService personService) {
_personService = personService;
_foundedList = new ObservableCollection<SearchPersonModel>();
_dispatcher = (/*CurrentApplication*/).Dispatcher;
_timer = new DispatcherTimer(
TimeSpan.FromMilliseconds(1000),
DispatcherPriority.Normal,
TimerCallBack,
_dispatcher);
_tokenSource = new CancellationTokenSource();
}
public string Term {
get { return _term; }
set {
// implementing INotifyPropertyChanged
if(_term== value)
return;
_term= value;
OnPropertyChanged(() => Term);
tokenSource.Cancel(); // canceling prev search query
_timer.Stop(); // stop the timer to reset it
// start it again to do a search query if user change not the term for 1000ms
_timer.Start();
}
}
private void TimerCallBack(object sender, EventArgs e) {
_timer.Stop();
_tokenSource = new CancellationTokenSource();
var task = Task<IEnumerable<SearchPersonModel>>.Factory
.StartNew(Search, _tokenSource.Token);
_dispatcher.BeginInvoke((Action)(() => {
_foundedList.Clear();
foreach(var item in task.Result)
_foundedList.Add(item);
}), DispatcherPriority.Background);
}
private IEnumerable<SearchPersonModel> Search() {
return _personService.DoSearch(this.Term);
}
}
并在IPersonService
实现中执行此操作:
public class PersonService : IPersonService {
public IEnumerable<SearchPersonModel> DoSearch(string term){
System.Threading.Thread.Sleep(10000);
return some-search-result;
}
}
但是,我希望在执行搜索查询时,GUI是免费的。但它冻结了!你知道我的错误在哪里吗?你能帮我吗?先谢谢!
答案 0 :(得分:4)
问题是评估task.Result
将阻止,直到查询完成。
最简单的选择可能是让Search
方法在最后执行_dispatcher.BeginInvoke
调用。
另一个选项 - 使用C#5将变得更容易 - 将是为任务添加延续,以便在完成任务时可以更新UI。目前你使用Task.ContinueWith
;使用C#5,您可以使用async
和await
。