当我将按钮单击事件与电话 (WP7) 上联系人的异步调用组合在一起时,我遇到了问题。问题是异步联系人调用的 SearchCompleted 事件在 Click 事件完成之前没有运行。这将在等待异步调用完成时导致无限循环。
在我的简化代码示例中,我有一个复选框和一个按钮。按下按钮时,将引发点击事件。如果选中该复选框,则会执行异步 SearchAsync 调用以获取手机上的所有联系人。
如果选中复选框,如何避免此代码将导致的无限循环:
private bool searchCompleted = false;
private Contact[] contacts;
private void button1_Click(object sender, RoutedEventArgs e)
{
Dictionary<int, string> contactList = new Dictionary<int,string>;
// ... add contacts to the contactList ...
contactList.Add(1, "a contact name");
// if CheckBox is checked add contacts from the phone Contacts
if (checkBoxContacts.IsChecked == true)
{
Contacts cons = new Contacts();
cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(Contacts_SearchCompleted);
cons.SearchAsync(string.Empty, FilterKind.None, null);
searchCompleted = false;
while (!searchCompleted)
{
Thread.Sleep(100);
}
int n = 1;
foreach (Contact contact in contacts)
{
contactList.Add(n, contact.DisplayName);
}
}
// .... add more namnes to the contactList from other places....
// .... do something with the contactList ....
// Navigate to the next dialog
NavigationService.Navigate(new Uri("/NextPage.xaml", UriKind.Relative));
}
private void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
contacts = e.Results.ToArray();
searchCompleted = true;
}
最佳答案
我最近遇到了类似的问题,我认为问题在于您在 button1_Click 中调用了 Thread.Sleep(),它在 UI 线程上运行不喜欢 Thread.Sleep() 或 .WaitOne() 等。
尝试在后台线程上执行您的一些按钮单击代码,并将您的联系人检索抽象为某种帮助类 - 我有类似这样的工作:
private void Button_Click(object sender, RoutedEventArgs e)
{
//this should be done asynchronously - "request" a person
List<Person> people = new List<Person>();
PersonService ps = new PersonService();
ThreadPool.QueueUserWorkItem(func =>
{
for (int i = 0; i < 10; i++)
{
people.Add(ps.GetRandomPerson()); //you need to call this on a separate thread or it will lock the ui thread.
}
Dispatcher.BeginInvoke(() => { Status.Text = "done"; }); //your button click method is now also asynchronous
});
}
/*** Helper class ***/
public class PersonService
{
AutoResetEvent sync = new AutoResetEvent(false);
public Person GetRandomPerson()
{
Person person = new Person();
Contacts contacts = new Contacts();
contacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
contacts.SearchAsync(String.Empty, FilterKind.None, person);
sync.WaitOne();
return person;
}
void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
Contact[] allContacts = e.Results.ToArray();
Contact randomContact = allContacts[new Random().Next(allContacts.Length)];
Person person = (Person)e.State;
person.Name = randomContact.DisplayName;
sync.Set();
}
}
请注意,这意味着您需要将按钮单击方法视为异步调用,因为您不知道后台线程何时会完成处理。
关于c# - 当我组合单击按钮和异步联系人调用时出现无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7701690/