0

可能重复:
跨线程操作无效:控件从线程访问,而不是它在
WPF 上创建的线程从其他线程访问 GUI

美好的一天,我写课

 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; 抛出异常 - “调用线程无法访问此对象,因为不同的线程拥有它。” 为什么?

4

2 回答 2

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;   
            }
        ));
于 2012-05-24T08:43:17.250 回答
1

您应该使用调度程序。例子:

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

在 WPF 和 Forms -> 你不能从不同的线程修改 UI 控件。

于 2012-05-24T08:45:27.863 回答