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方法的最后一行收到 Collection modify 异常。

我尝试了 lock 和 Dispatcher.CurrentDispatcher.BeginInvoke 与 _graphPlottingTimer_Elapsed 但它仍然给出相同的异常。

4

4 回答 4

1

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

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

于 2013-07-08T08:03:56.803 回答
0

为什么不使用线程安全集合?它们允许修改来自不同线程的集合以及处理潜在问题。

于 2013-07-08T08:19:43.317 回答
0

请考虑以下示例:来自 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);
            }
        }
    }
于 2013-07-08T08:04:55.790 回答
0

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

于 2013-07-08T08:01:25.537 回答