使用线程时内存不足异常
本文关键字:内存不足 异常 线程 | 更新日期: 2023-09-27 18:05:10
我有以下算法,
private void writetodb()
{
using(var reader = File.OpenRead("C:'Data.csv");
using(var parser = new TextFieldParser(reader))
{
//Do some opeartions
while(!parser.EndOfData)
{
//Do operations
//Take 500 rows of data and put it in dataset
Thread thread = new thread(() => WriteTodb(tablename, set));
thread.Start();
Thread.Sleep(5000);
}
}
}
public void WriteTodb(string table, CellSet set)
{
//WriteToDB
//Edit: This statement will write to hbase db in hdinsight
hbase.StoreCells(TableName, set);
}
此方法在 500mb数据之前工作得很好,但在此之后它失败了,说Out of memory exception
.
我很确定这是因为线程,但使用线程是强制性的,我不能改变架构。
有没有人能告诉我在上面的程序中,我必须在线程编程中做哪些修改来避免内存异常?
首先,我不明白你说的关于线程:
我不得不在线程编程中使上述程序避免内存例外。
如果您使用TPL
,您将使用线程编程,正如已经建议的那样。如果你不能理解Thread
类,你真的不必使用它。您说您的代码是C# 4.0
,因此TPL
是您的选项。你可以这样做(非常简单的方法):
List<Task> tasks = new List<Task>();
while(!parser.EndOfData)
{
tasks.Add(Task.Run(() => WriteTodb(tablename, set)));
}
Task.WaitAll(tasks.ToArray());
TPL引擎将使用默认的TaskScheduler
类,它使用内部ThreadPool
,并可以在服务器上设置资源级别。
另外,我看到你正在使用微软的HBase
客户端,它有async
方法:
public async Task StoreCellsAsync(string table, CellSet cells)
{
}
因此,您可以在代码和 TPL
中同时使用异步方法:
List<Task> tasks = new List<Task>();
while(!parser.EndOfData)
{
tasks.Add(WriteTodb(tablename, set)));
}
// asynchroniously await all the writes
await Task.WhenAll(tasks.ToArray());
public async Task WriteTodb(string table,CellSet set)
{
//WriteToDB
//Edit: This statement will write to hbase db in hdinsight asynchroniously!
await hbase.StoreCellsAsync(TableName, set);
}
如果,由于一些奇怪的原因,你不能使用TPL
,你必须重构你的代码并编写你自己的线程调度程序:
- 你不必每次都为你的写创建线程,你可以重用它们。
- 在同一个线程内运行第二次,通常比为每个操作创建两个不同的线程快。
- 将文件分割成几个部分,创建写线程,循环写数据。
使用ThreadPool.QueueUserWorkItem代替每次创建新线程。参考:https://msdn.microsoft.com/en-us/library/kbf0f1ct(v=vs.110).aspx