如何处理此错误:集合已被修改;枚举操作可能无法执行。 [英] How to handle this error: Collection was modified; enumeration operation may not execute.

查看:101
本文介绍了如何处理此错误:集合已被修改;枚举操作可能无法执行。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello Experts



在我的项目中,我创建了许多事务并将它们存储在dataGridView中,并附带详细信息。

当按下startbtn时代码将执行:

Hello Experts

In my Project, I create many transaction and store them in dataGridView with their details.
When press startbtn this code will execute:

Manager manager = new Manager(GridView);



这里是经理类:


ANd here is the Manager class:

public class Manager 
{
  public static Dictionary<Thread, int> ThreadList;
  public static DataTable DisposableThreads;

  
  public Manager(DataGridView dgv)
  {
     ThreadList = new Dictionary<Thread, int>();
     DisposableThreads = new DataTable();
     DisposableThreads.Columns.Add(new DataColumn("Thread", typeof(Thread)));

     DisposableThreads.RowChanged += RowChanged;
   
     foreach (DataGridViewRow row in dgv.Rows)
     {
        Thread thread = new Thread(() => Transaction(dgv, (row as GridRow).Row));
   
        ThreadList.Add(thread, (row as GridRow).Row);
        thread.Start();
     }            
  }

  private void RowChanged(object sender, DataRowChangeEventArgs e)
  {
     if (e.Action == DataRowAction.Add)
     {
        ThreadList.Remove((Thread)e.Row.ItemArray[0]);
        DisposableThreads.Rows.Remove(e.Row);
     }
  }

  public void Transaction(DataGridView dataGridView, int row)
  {
     // Some Code
     DisposableThreads.Rows.Add(new object[] { Thread.CurrentThread });
  }
}



一切顺利。

但有时我按停止按钮取消正在运行的线程发生以下异常。


Every thing goes fine.
But sometimes when I press stop button to cancel the running threads the below exeception occurs.

Collection was modified; enumeration operation may not execute.



停止按钮中的代码是:


The code in Stop button is:

private void Stop_Click(object sender, EventArgs e)
{
  try
  {
     foreach (Thread t in Manager.ThreadList.Keys)
     {
        if (t.ThreadState == System.Threading.ThreadState.Running)
           t.Abort(); // they really do not abort by this code !!??

     } 
     MessageBox.Show("All operations canceled successfully.");
  }
  catch (Exception ex)
  {
     MessageBox.Show(ex.Message);
  }
}

推荐答案

它似乎在你的停止按钮点击你正在访问Manager.ThreadList.Keys

及其静态对象(它意味着由System处理)所以当你使用字典对象时它是可修改的。所以这里的情况是,一个功能是不断修改该集合,同时stop_Click正在使用它...

所以在这里你可以做一件事......









Its seems like in your stop button click you are accessing Manager.ThreadList.Keys
and its static object (it means handled by System) so when you are using dictionary object its modifiable. SO here situation is that one function is continuously modifying that collection and meanwhile stop_Click is using it...
So here you can do one thing ...




private void Stop_Click(object sender, EventArgs e)
{
  try
  {
    Dictionary<thread,> TempThreadList = new Dictionary<thread,>();
    while(Manager.ThreadList.Keys.Count > 0) //will run upto there is any thread is running.
{
  TempThreadList=Manager.ThreadList; //added one more container for continuosly changing collection.

     foreach (Thread t in TempThreadList.Keys)
     {
        if (t.ThreadState == System.Threading.ThreadState.Running)
           t.Abort(); // they really do not abort by this code !!??

     }
}
     MessageBox.Show("All operations canceled successfully.");
  }
  catch (Exception ex)
  {
     MessageBox.Show(ex.Message);
  }
}


我通过这种方式更改stop_Click方法:

I change stop_Click method by this way:
try
{
   while (Manager.ThreadList.Count != 0)
   {
      var t = Manager.ThreadList.FirstOrDefault(x => (x.Key as Thread).IsAlive == true);
                   
      Manager.DisposableThreads.Rows.Add(t.Key);
   }
  
   MessageBox.Show("All operation canceled successfully.");
}
catch (Exception ex)
{
   MessageBox.Show(ex.Message);
}



RowChanged方法也改变如下:


Also the RowChanged method changes like this:

private void RowChanged(object sender, DataRowChangeEventArgs e)
{
  if (e.Action == DataRowAction.Add)
  {
      if (((Thread)e.Row.ItemArray[0]).IsAlive)
          ((Thread)e.Row.ItemArray[0]).Abort();

      ThreadList.Remove((Thread)e.Row.ItemArray[0]);
      DisposableThreads.Rows.Remove(e.Row);
    }
}


这篇关于如何处理此错误:集合已被修改;枚举操作可能无法执行。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆