2013-07-08 47 views
1
Public ObservableCollection<T> SharedObj=new ObservableCollection<T>(); 

Thread mainThread = new Thread(() => MainThreadMethod(SharedObj);                      
mainThread.Start(); 

private DispatcherTimer _graphPlottingTimer=new DispatcherTimer(); 
_graphPlottingTimer.Tick += new EventHandler(_graphPlottingTimer_Tick); 
_graphPlottingTimer.Interval = TimeSpan.FromMilliseconds(100); 
_graphPlottingTimer.Start(); 

private void MainThreadMethod(ObservableCollection<T> obj) 
{ 
    //here i am adding rows in obj . 
} 

void _graphPlottingTimer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    private List<T> refinedList=new List<T>(); 

    //I am getting a Collection Modify Exception on the below line 
    refinedList =SharedObj.Where(condition).ToList(); 
} 

我正在收集修改的的最后一行例外_graphPlottingTimer_Elapsed上述方法。分享的对象,在多发线程

我试着锁和Dispatcher.CurrentDispatcher.BeginInvoke与_graphPlottingTimer_Elapsed 但它仍然给予相同的例外。

回答

0

每次访问ShareObj时,都需要锁定它。声明一个全局对象,并在每次访问它时用相同的全局对象锁定ShareObj。希望这可以帮助!

+0

锁(thislock){refinedList = SharedObj.Where(condition).ToList();} –

+0

但这不适合我,你可以请给其他解决方案。 thnks –

+0

您正在修改MainThreadMethod中的集合,是吗?您还需要将其锁定在那里:每当您访问obj时,都需要使用锁定列表的同一字段来锁定它。 此外,为线程安全声明SharedObj静态。 –

1

当您共享资源时,您需要同步访问权限。在你的情况下,你的代码在你的线程中的.Where()被枚举时修改了一个共享集合。

您需要使用syncronizing对象。在C#中实现这个最简单的方法是lock-Statement

+0

我已经尝试锁定锁(thislock){} –

+0

锁(thislock){refinedList = SharedObj.Where(condition).ToList();} –

+0

仍然给它的集合修改异常 –

0

请考虑下面的例子:sample from MSDN

您必须声明私有变量,当您更新列表锁定。

简单的例子:

internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      List<Thread> threads = new List<Thread>(); 
      ThreadTest tt = new ThreadTest(); 
      for (int i = 0; i < 10; i++) 
      { 
       // alter the varialbe shared 
       lock (tt.thisLock) 
       { 
        Thread t = new Thread(() => tt.DoAction(string.Format("Thread-{0}", i))); 
        threads.Add(t); 
        t.Start(); 
       } 
      } 
      // wait after each thread 
      foreach (Thread item in threads) 
      { 
       item.Join(); 
      } 
      tt.ReadList(); 

      Console.ReadKey(); 
     } 
    } 

    internal class ThreadTest 
    { 
     public Object thisLock = new Object(); 
     protected IList<string> myList = new List<string>(); 

     public void DoAction(string info) 
     { 
      myList.Add(info); 
     } 

     public void ReadList() 
     { 
      foreach (string item in myList) 
      { 
       Console.WriteLine(item); 
      } 
     } 
    } 
+0

感谢Matthieu!我试过这个,私人对象thisLock = new Object();仍然有例外 –

+0

你有什么例外? –

+0

收集修改异常 –