线程和事件

时间:2012-05-24 08:39:01

标签: c# .net wpf multithreading events

  

可能重复:
  Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
  WPF access GUI from other thread

美好的一天, 我写课

 public class Metric1
 {
        public event MetricUnitEventHandler OnUnitRead;


       public void ReiseEventOnUnitRead(string MetricUnitKey)
       {
            if (OnUnitRead!=null)
             OnUnitRead(this,new MetricUnitEventArgs(MetricUnitKey));
        }   
 .....
 }    

 Metric1 m1 = new Metric1();
 m1.OnUnitRead += new MetricUnitEventHandler(m1_OnUnitRead);

 void m1_OnUnitRead(object sender, MetricUnitEventArgs e)
 {
        MetricUnits.Add(((Metric1)sender));
        lstMetricUnit.ItemsSource = null;
        lstMetricUnit.ItemsSource = MetricUnits;    
 } 

然后我开始每分钟调用m1的ReiseEventOnUnitRead方法的新线程。

在行lstMetricUnit.ItemsSource = null;抛出异常 - “调用线程无法访问此对象,因为另一个线程拥有它。”为什么?

2 个答案:

答案 0 :(得分:3)

您无法从不是GUI线程的其他线程更改GUI项目

如果您正在使用WinForms,请使用Invoke和InvokeRequired。

if (lstMetricUnit.InvokeRequired)
{        
    // Execute the specified delegate on the thread that owns
    // 'lstMetricUnit' control's underlying window handle.
    lstMetricUnit.Invoke(lstMetricUnit.myDelegate);        
}
else
{
    lstMetricUnit.ItemsSource = null;
    lstMetricUnit.ItemsSource = MetricUnits;
}

如果您正在使用WPF,请使用Dispatcher。

lstMetricUnit.Dispatcher.Invoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
              lstMetricUnit.ItemsSource = null;
              lstMetricUnit.ItemsSource = MetricUnits;   
            }
        ));

答案 1 :(得分:1)

您应该使用Dispatcher。 例如:

Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {  
        lstMetricUnit.ItemsSource = null;
        lstMetricUnit.ItemsSource = MetricUnits;    
})));

在WPF和表单中 - >你无法从不同的线程修改UI控件。