我是C#和线程的新手,这是一个非常简单的问题,但让我真的陷入困境。我在这个网站上搜索过但找不到与我的情景类似的答案:
我有一个方法说Parent(),并且我创建了一个类型列表,每次第n次将它传递给一个Task。我有什么时候清除列表并释放内存的问题,因为它不断增长。我在任务结束时尝试清除列表,如果我使用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();
}
}
}
答案 0 :(得分:6)
你有一个关闭错误。
在新() => WriteToDB(new List<MyType>(list))
开始之前,不会执行lambda Task
。
这有时是在您致电list.Clear()
之后。
修复是捕获lambda之外的列表副本:
var chunk = new List<MyType>(list);
Task.Factory.StartNew(() => WriteToDB(chunk));
list.Clear();
答案 1 :(得分:1)
在启动线程之前创建新列表:
var newList = new List<MyType>(list);
Task.Factory.StartNew(() => WriteToDB(newList));
list.Clear();
这样,新列表在新线程启动之前就已准备就绪,因此可以立即清除原始列表。
答案 2 :(得分: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));
}