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 但它仍然给出了同样的例外。
答案 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?它们允许从不同的线程修改集合以及处理潜在的问题。