0

Possible Duplicate:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
WPF access GUI from other thread

Good day , I write class

 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;    
 } 

Then i start new thread that every minute calls m1's ReiseEventOnUnitRead method.

In row lstMetricUnit.ItemsSource = null; throws excepition - "The calling thread cannot access this object because a different thread owns it." Why?

Community
  • 1
  • 1
Armen Khachatryan
  • 831
  • 3
  • 22
  • 37
  • 4
    This has been asked & answered many times. Here's a [List](http://stackoverflow.com/search?q=wpf+%22other+thread%22) – H H May 24 '12 at 08:44

2 Answers2

3

You cannot change GUI item from another thread that isn't the GUI thread,

If you are working with WinForms use Invoke and 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;
}

If you are working with WPF use Dispatcher.

lstMetricUnit.Dispatcher.Invoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
              lstMetricUnit.ItemsSource = null;
              lstMetricUnit.ItemsSource = MetricUnits;   
            }
        ));
Dor Cohen
  • 16,769
  • 23
  • 93
  • 161
1

You should use Dispatcher. Example:

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

In WPF and Forms -> you cannot modify UI controls from different thread.

Kamil Lach
  • 4,519
  • 2
  • 19
  • 20