我正在尝试运行此代码( 正在运行):
foreach(Friend f in chatLib.Friends)
{
chatLib.GetPhoto(f);
contactWindowControl.AddContactToList(f);
}
在它自己的主题中,以便不阻止UI 我试过以下:
chatLib.Friends.ForEach(item =>
new Thread(() => {
Dispatcher.BeginInvoke(new Action<Friend>(chatLib.GetPhoto), item);
Dispatcher.BeginInvoke(new Action<Friend>(contactWindowControl.AddContactToList), item);
})
);
我也试过没有 Lambda 。
GetPhoto (来自聊天图书馆)
public void GetPhoto(Friend contact)
{
VcardIq viq = new VcardIq(IqType.get, new Jid(contact.jid));
IQ iq = xmpp.IqGrabber.SendIq(viq);
if (iq != null && iq.Type == IqType.result)
{
Vcard vcard = iq.Vcard;
if (vcard != null)
{
contact.photo = vcard.Photo.Image;
contact.hasPhoto = true;
}
}
}
AddContactToList (来自usercontrol后面的代码)
public void AddContactToList(Friend contact)
{
contactScroll.Children.Add(new ContactWindowContact(contact));
}
答案 0 :(得分:1)
因为你在线程中什么都不做,基本上你是说创建一个新线程,然后用Dispatcher注册代码,以便代码在UI线程上运行。
没有神奇的“make things threaded”,你正在做什么创建一个线程,然后将你想要做的工作推回原来的线程。
您需要做的是制作代码,以便getphoto返回您需要的内容,并且不会更新UI线程上使用的任何内容(因此任何绑定到xaml /树中任何内容的内容),然后当您完成此操作时工作调用调度程序只传递代码来更新数据
此外你真的不应该为此创建自己的线程,只是使用任务或更好,因为你已经使用foreach切换到parallel.foreach
Parallel.Foreach(chatLib.Friends,item=>
{
// This runs in parallel, do the expensive work here and NOT Inside Dispatcher
item.Photo = chatLib.getPhoto(item);
Dispatcher.BeginInvoke(()=>
{
// This will run on the UI thread, only do updates here
contactWindowControl.AddContactToList(item);
});
});
答案 1 :(得分:0)
我认为最好使用任务而不是调度程序。
您的代码如下所示:
List<Task> tasks = new List<Task>();
foreach(Friend f in chatLib.Friends)
{
Task task = Task.Factory.StartNew( ( arg ) =>
{chatLib.GetPhoto(arg); contactWindowControl.AddContactToList(arg); }, f );
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());