我正在处理WPF-MVVM项目,并且在某些后台线程中实现了异步无限循环。我在ViewModel中所做的是
public TestVM()
{
LineIO_Task();
//some other work
}
并且LineIO_Task定义为
public void LineIO_Task()
{
foreach (Line l in Lines)
{
Task GetP = new Task(() => { EnPost(l); }, TaskCreationOptions.LongRunning);
GetP.Start();
//EnPost(Lines[i]);
}
}
Lines是在TestVm中初始化的ObservableCollection。Lines中有7个项目。而EnPost被定义为
public async void EnPost(Line l)
{
try
{
int last = 0;
while (true)
{
int pno = l.Com.ReadPostNo();//read a serial port
if (pno != last && pno != -1 && pno != 0)
{
Dispatcher.Invoke(() =>
{
Post p = AssignedPost.First(x => x.Num == pno);
if (p == null)
{
LocalDb.InsertPost(l.Num, new Post(pno));
}
else
{
if (p.ToLine != l.Num)
{
//update UI
Lines.First(n => n.Num == p.ToLine).Posts.First(y => y.Num == p.Num).IsValid = true;
Lines.First(n => n.Num == p.ToLine).OnPropertyChanged("RealPostCount");
}
}
});
last = pno;
}
await Task.Delay(150);
}
}
catch (Exception ex)
{
//
}
}
AssignedPost是Post的ObservableCollection。 Post具有int属性ToLine和Num。 我有一个名为Assign的函数,该函数将项目添加到AssignedPost中。
private int Assign(Post p)
{
int ln;
//evaluate ln by some algorithm
p.ToLine = ln;
AssignedPost.Add(p);
//some other work
return ln;
}
问题是该项目已添加到AssignedPost中,即Post p = AssignedPost.First(x => x.Num == pno);
p不为null。但是应该在插入之前分配的p.ToLine始终为0。因此,该错误使UI更新引发了错误。我不明白为什么。它与多线程有关吗?
答案 0 :(得分:0)
您无法从任何其他线程触摸UI线程,否则会遇到问题。
当您要为UI更新某些内容时,您需要执行以下操作:
View.Dispatcher.InvokeAsync(a.Invoke, p);
将避免对UI线程的调用进行编组。
如果您使用类似ObservableCollection之类的东西,则可以使用集合同步从另一个线程中调用它,并且对INotifyPropertyChanged的调用将被编组到UI线程中。
BindingOperations.EnableCollectionSynchronization(Entries);
请确保在完成操作后将其关闭,以免发生内存泄漏:
BindingOperations.DisableCollectionSynchronization(Entries);