Here is my problem: I am creating a WP7 application and need to list all contacts on the mobile device. I know there is the Contacts class with method SearchAsync and SearchCompleted event handler.
This is all working except for one detail; when I am using the application on my phone, the search takes more than 12 seconds! I am using data virtualization to make the UI draw quickly. I have about 400 contacts in my phone. So the problem is, that SearchCompleted is fired after a long time 🙁
Do you have any ideas how to improve this solution? Should I start inserting contacts in listbox by first letter (“a”, “b”… but then that means I need to call SearchAsync repeatedly) and then how can I merge it?
Device: Samsung Omnia 7
ThreadPool.QueueUserWorkItem(result =>
{
_cachingRunning = true;
var contacts = new Contacts();
contacts.SearchCompleted += contacts_SearchCompleted;
contacts.SearchAsync(string.Empty, FilterKind.None, null);
});
This method is called almost 12 second after SearchAsync:
private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
_phoneContacts = e.Results;
Count = e.Results.Count();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
Cached = true;
_cachingRunning = false;
CachingChanged();
});
}
I store _phoneContacts and then use it for filtering; accessing it by Index and Count during data virtualization on ListBox.
This method “works” with VirtualizingDataCollection (Telerik) and creates ViewModel item which is added to VirtualizingDataCollection.
public ObservableCollection<ExtendedContactModel> GetContactsRange(int startIndex, int count)
{
var collection = new ObservableCollection<ExtendedContactModel>();
for (var i = startIndex; i < startIndex + count; i++)
{
var vo = ConvertToVO(_phoneContacts.ElementAt(i));
var newContact = ConvertToExtendedContactModel(_phoneContacts.ElementAt(i), vo);
collection.Add(newContact);
}
return collection;
}
If this is a Mango device you have a couple of options:
1)Use a background task to push contact information into an application-specific data store. The standard background task runs every 30 minutes and is allowed to take about 30 seconds to execute. More info on the background agent can be found here: Background Agents
2)If the background agent is too scary you can do all this in-process. When the user opens the app up a background thread can gather the contacts list and save them to an internal store.
While you’d need to spend time managing the internal store of contacts, it allows you to control the contact list and will definitely improve the user experience as they’ll think the contact search is very fast.