使用线程时出现内存不足异常

Out of memory exception while using threads

我有以下算法,

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);
}

此方法在 500 mb 数据 之前绝对有效,但之后它无法显示 Out of memory exception.

我很确定这是因为线程,但使用线程是强制性的,我无法更改体系结构。
谁能告诉我在上面的程序中线程编程需要做哪些修改才能避免内存异常。

而不是每次都创建新线程使用ThreadPool.QueueUserWorkItem。作为参考,请参阅:https://msdn.microsoft.com/en-us/library/kbf0f1ct(v=vs.110).aspx

首先,我无法理解你所说的线程:

I have to make in thread programming in the above program to avoid memory exception.

如果你使用TPL,你将使用线程编程,正如已经建议的那样。 Thread class 看不懂就真的不用了。你说你的代码是 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 class,它使用内部 ThreadPool 并且可以平衡您在服务器上拥有的资源。

此外,我看到您使用的是 Microsoft 的 HBase 客户端,其中 it has async method:

public async Task StoreCellsAsync(string table, CellSet cells)
{
}

所以你可以use the asynchronious approach in your code and TPL at the same time:

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,您必须重构代码并编写自己的线程调度程序:

  1. 您不必每次都为您的写入创建线程,您可以重复使用它们。
  2. 运行 第二次进入同一个线程通常比为每个操作创建两个不同的线程要快。
  3. 将文件拆分成几个部分,创建写入线程,循环写入数据。