C#属性分配错误

时间:2018-08-23 10:38:56

标签: c# wpf multithreading

我正在处理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更新引发了错误。我不明白为什么。它与多线程有关吗?

1 个答案:

答案 0 :(得分:0)

您无法从任何其他线程触摸UI线程,否则会遇到问题。

当您要为UI更新某些内容时,您需要执行以下操作:

View.Dispatcher.InvokeAsync(a.Invoke, p);

将避免对UI线程的调用进行编组。

如果您使用类似ObservableCollection之类的东西,则可以使用集合同步从另一个线程中调用它,并且对INotifyPropertyChanged的调用将被编组到UI线程中。

BindingOperations.EnableCollectionSynchronization(Entries);

请确保在完成操作后将其关闭,以免发生内存泄漏:

BindingOperations.DisableCollectionSynchronization(Entries);