5

我是 C# 和线程的新手,这是一个非常简单的问题,但我真的卡住了。我确实在此站点上进行了搜索,但找不到与我的情况类似的答案:

我有一个方法说 Parent() 并且我创建一个类型化列表,每次我将它传递给一个任务。我有什么时候清除列表和释放内存的问题,因为它一直在增长。我尝试在任务结束时清除列表,如果我使用 Parent 方法清除列表,则线程中的列表为空。

有人可以帮助我吗?我知道这是一个非常简单的问题,但希望能得到帮助。

    public void Parent()
    {
     List<MyType> list = new List<MyType>();
     for (int i = 0; i< N; i++)
     {
        list.Add(new MyType {Var = "blah"});

      if ( i% 10 == 0) //every tentth time we send a task out tou a thread
      {
       Task.Factory.StartNew(() => WriteToDB(new List<MyType>(list))); 
       //here I am              sending a new instance of the list

        //Task.Factory.StartNew(() => WriteToDB((list))); 
        //here I am sending same instance

        list.Clear();

         //if I clear here the list sent to the WriteToDB is empty
        //if I do not, the memory keeps growing up and crashes the app 
      }

      private void WriteToDB(List<MyType> list)
      {
       //do some calculations with the list 
       //insert into db 
       list.Clear(); 
      }
     }
   }
4

3 回答 3

7

你有一个关闭错误。

在新的开始() => WriteToDB(new List<MyType>(list))之前不会执行lambda 。Task这有时会在您致电list.Clear().

修复方法是在 lambda 之外捕获列表的副本:

var chunk = new List<MyType>(list);
Task.Factory.StartNew(() => WriteToDB(chunk));

list.Clear();
于 2012-12-01T10:39:17.773 回答
1

只需在启动线程之前创建新列表:

var newList = new List<MyType>(list);
Task.Factory.StartNew(() => WriteToDB(newList)); 
list.Clear();

这样,新列表在新线程开始之前就准备好了,因此立即清除原始列表是安全的。

于 2012-12-01T10:34:56.117 回答
1
if ( i% 10 == 0) //every tentth time we send a task out tou a thread
{
   // clone your list before starting the task
   var listToProcess = new List<MyType>(list);
   list.Clear();

   Task.Factory.StartNew(() => WriteToDB(listToProcess)); 
}
于 2012-12-01T10:56:32.053 回答