在ListView中的Key Down上加载联系人

时间:2014-08-13 13:41:51

标签: xaml windows-runtime winrt-xaml windows-phone-8.1

我使用以下代码使用ContactStore加载联系人。我的要求是在文本框中按下键时搜索ContactStore中的联系人。以下是我的View模型中的代码。

   private async void LoadAllContacts(string searchQuery)
    {
        ContactStore contactStore = await ContactManager.RequestStoreAsync();

        IReadOnlyList<Contact> contacts = null;
        // Find all contacts
        contacts = await contactStore.FindContactsAsync(searchQuery);

        foreach (var item in contacts)
        {
            if (!string.IsNullOrEmpty(item.FirstName) && !string.IsNullOrEmpty(item.LastName))
            {
                var contact = new Member
                {
                    FirstName = item.FirstName,
                    LastName = item.LastName,
                    FullName = item.DisplayName, //item.HonorificNamePrefix ?? "" + item.FirstName + item.MiddleName ?? "" + item.LastName,
                    Bio = item.Notes
                };
                if (item.DataSuppliers != null)
                {
                    foreach (var dataSupplier in item.DataSuppliers)
                    {
                        switch (dataSupplier.ToLower())
                        {
                            case "facebook":
                                break;
                            case "hotmail2":
                            case "hotmail":
                                break;
                        }
                    }
                }
                if (item.Thumbnail != null)
                {
                    var thumnailStream = await item.Thumbnail.OpenReadAsync();
                    BitmapImage thumbImage = new BitmapImage();
                    thumbImage.SetSource(thumnailStream);
                    contact.ImageSource = thumbImage;
                }
                this.Insert(0, contact);
            }
        }
    }

联系人在我的列表视图中完美加载,但问题是从联系人存储区加载联系人是一项繁重的任务,当用户我快速按下文本框中的文本时,应用程序会抛出异常。

我的问题是如何有效地加载联系人?意味着如果用户按下“a”并且我调用此方法并且快速用户按下“c”,那么如果结果加载为“a”,则应用程序应取消继续之前的操作并加载“ac”相关联系人。

感谢。

1 个答案:

答案 0 :(得分:2)

您应该阅读CancellationTokens的概念。这就是你正在寻找的想法。网上有很多例子。

CancellationToken / CancellationTokenSource是C#管理和取消任务的方式。

在您的情况下,您将创建一个CancellationTokenSource,并在您的ContactManager.RequestStoreAsync(CancellationToken token)contactStore.FindContactsAsync(CancellationToken token)方法(您正在等待的任何异步方法)中传递其Token对象。

这两种方法应该接受CancellationToken,偶尔会做token.ThrowIfCancellationRequested()

如果在某些时候您发现要停止当前任务并启动一个新任务(对于您的情况,当用户键入新内容时),请调用CancellationTokenSource.Cancel(),这将终止正在运行的任务线程,因为ThrowIfCancellationRequested()


我想指出的一件事是,在通过CancellationTokens之前,您的代码可以进一步优化。您每次都致电ContactStore contactStore = await ContactManager.RequestStoreAsync();。你能否将它存储为成员变量?

你也可以做一些技巧,比如没有运行你的加载联系人方法,除非用户已经停止输入1秒钟,我建议你在这种情况下使用ConcurrentExclusiveSchedular强制执行并发任务。