在多个线程中共享一个对象

时间:2013-07-08 07:55:50

标签: c# wpf multithreading

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修饰例外。

我用_graphPlottingTimer_Elapsed尝试了lock和Dispatcher.CurrentDispatcher.BeginInvoke 但它仍然给出了同样的例外。

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分: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);
            }
        }
    }

答案 3 :(得分:0)

为什么不使用Thread-Safe Collection?它们允许从不同的线程修改集合以及处理潜在的问题。