Windows 8搜索魅力的实现逻辑

作为一名技术爱好者,阅读了大量关于Windows 8的技术资料。特别关注到一点,那就是需要保持用户界面的流畅性,因为任何超过30/300毫秒的延迟在触摸系统中都会让人感觉到卡顿。这意味着什么?这意味着需要在需要的地方使用Async/Await来保持代码的异步执行。到目前为止,一切顺利。

现在,让来谈谈搜索魅力。显然在清单文件中启用了这个功能。然后,编写了以下代码,期望它能够正常工作:

sealed partial class App : Application { public App() { this.InitializeComponent(); this.Suspending += OnSuspending; } protected override async void OnLaunched(LaunchActivatedEventArgs args) { // ... // ... // ... SetupSearch(); } private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); await SuspensionManager.SaveAsync(); deferral.Complete(); } private void SetupSearch() { var searchPane = SearchPane.GetForCurrentView(); searchPane.SuggestionsRequested += searchPane_SuggestionsRequested; searchPane.ResultSuggestionChosen += searchPane_ResultSuggestionChosen; } void searchPane_ResultSuggestionChosen(SearchPane sender, SearchPaneResultSuggestionChosenEventArgs args) { MessageDialog dialog = new MessageDialog(string.Format("You picked {0}", args.Tag)); dialog.ShowAsync(); } async void searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args) { var suggestions = Enumerable.Range(1, 2).Select(x => new { Desc = string.Format("{0}_{1}", args.QueryText, x.ToString()), Id = x }); // 模拟等待更有意义的操作(例如网络服务等) await Task.Delay(2000); var imageUri = new Uri("ms-appx:///Assets/search40.png"); var imageSource = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(imageUri); args.Request.SearchSuggestionCollection.AppendSearchSeparator("Demo Suggestions"); foreach (var suggestion in suggestions) { args.Request.SearchSuggestionCollection.AppendResultSuggestion("Suggestion", suggestion.Desc, suggestion.Id.ToString(), imageSource, ""); } } }

看起来代码是合理的。但是当运行这段代码时,遇到了一个异常。这真是非常奇怪。

事实证明,这个问题有一个解决方案,但是这个解决方案的文档非常不完整。实际上,它借鉴了很多jQuery的Deferred模式(可以在这里了解更多)。

那么解决方案是什么呢?正如所说,WinRT确实借鉴了jQuery的Deferral / Promise理念。请求一个Deferrable对象,做一些工作,然后完成这个Deferrable对象。

以下是使用WinRT Deferrable对象重构的代码。这种技术可以用于大多数魅力功能。

sealed partial class App : Application { public App() { this.InitializeComponent(); this.Suspending += OnSuspending; } protected override async void OnLaunched(LaunchActivatedEventArgs args) { // ... // ... // ... SetupSearch(); } private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); await SuspensionManager.SaveAsync(); deferral.Complete(); } private void SetupSearch() { var searchPane = SearchPane.GetForCurrentView(); searchPane.SuggestionsRequested += searchPane_SuggestionsRequested; searchPane.ResultSuggestionChosen += searchPane_ResultSuggestionChosen; } void searchPane_ResultSuggestionChosen(SearchPane sender, SearchPaneResultSuggestionChosenEventArgs args) { MessageDialog dialog = new MessageDialog(string.Format("You picked {0}", args.Tag)); dialog.ShowAsync(); } async void searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args) { var suggestions = Enumerable.Range(1, 2).Select(x => new { Desc = string.Format("{0}_{1}", args.QueryText, x.ToString()), Id = x }); // FIXED CODE: Use args.Request.GetDeferral() / deferral.Complete var deferral = args.Request.GetDeferral(); await Task.Delay(2000); var imageUri = new Uri("ms-appx:///Assets/search40.png"); var imageSource = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(imageUri); args.Request.SearchSuggestionCollection.AppendSearchSeparator("Demo Suggestions"); foreach (var suggestion in suggestions) { args.Request.SearchSuggestionCollection.AppendResultSuggestion("Suggestion", suggestion.Desc, suggestion.Id.ToString(), imageSource, ""); } deferral.Complete(); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485