当前位置: 首页 > 知识库问答 >
问题:

惰性加载从using语句获得的列表

周志文
2023-03-14

我正在使用CSVHelper库读取CSV文件。但这不是你想要的

请参阅以下代码

public class Reader
{
    public IEnumerable<CSVModel> Read(string file)
    {
       using var reader = new StreamReader(@"C:\Users\z0042d8s\Desktop\GST invoice\RISK All RISKs_RM - Copy.CSV");
       using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
       IEnumerable<CSVModel> records = csv.GetRecords<CSVModel>();
       return records;
    }
}

上面方法中的CSV.getRecords使用yield返回,并在每一个CSV行被读取后立即返回,而不是等到整个CSV文件被读取后再返回(从CSV流数据)

我有一个consumer类,顾名思义,它使用Read方法返回的数据。


class Consumer
{
   public void Consume(IEnumerable<CSVModel> data)
   {
      foreach(var item in data)
      {
         //Do whatever you want with the data. I am gonna log it to the console
         Console.WriteLine(item);
      }
}


下面是调用方

   public static void main()
   {
      var data = new Reader().Read();
      new Consumer().Consume();
   }

希望我没有失去你。

我面临的问题就在下面

由于上面的数据变量是IEnumerable的,所以它将被惰性加载(换句话说,只要不迭代,它就不会读取CSV文件)。但是,当我调用consumer()方法时,它对数据变量进行迭代,强制读取Read()方法中的CSV文件,using语句中的读取器和CSV对象将被释放,引发ObjectDisported异常。

此外,我不想删除using块之外的reader和csv对象,因为它们应该被处理以防止内存泄漏。

异常消息如下

    System.ObjectDisposedException: 'GetRecords<T>() returns an IEnumerable<T> 
    that yields records. This means that the method isn't actually called until 
    you try and access the values. e.g. .ToList() Did you create CsvReader inside 
    a using block and are now trying to access the records outside of that using 
    block?

而且我知道我可以使用贪婪运算符(.toList())。但我想让懒惰的装入工作。

请建议是否有任何出路。

提前道谢。

共有1个答案

袁元明
2023-03-14

您可以将操作作为参数传递给读取器。它稍微改变了方法的思想:

public class Reader
{
    public void Read(string file, Action<CSVModel> action)
    {
        using var reader = new StreamReader(@"C:\Users\z0042d8s\Desktop\GST invoice\RISK All RISKs_RM - Copy.CSV");
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        
        IEnumerable<CSVModel> records = csv.GetRecords<CSVModel>();

        foreach(var record in records){
            action(record);
        }
    }
}

class Consumer
{
    public void Consume(CSVModel data)
    {
        //Do whatever you want with the data. I am gonna log it to the console
        Console.WriteLine(item);
    }
}

public static void Main()
{
    var consumer = new Consumer();
    new Reader().Read(consumer.Consume); // Pass the action here 
}

或者,您可以使整个Reader类都是一次性的:

public class Reader : IDisposable
{
    private readonly StreamReader _reader;
    private readonly CsvReader _csv;

    public Reader(string file)
    {
        _reader = new StreamReader(file);
        _csv = new CsvReader(_reader, CultureInfo.InvariantCulture);
    }

    public IEnumerable<CSVModel> Read()
    {
        return csv.GetRecords<CSVModel>();                   
    }

    public void Dispose() => Dispose(true);

    protected virtual void Dispose(bool disposing)
    {
        if (_disposed)
        {
            return;
        }

        if (disposing)
        {
           _csv.Dispose();
           _reader.Dispose();
        }

        _disposed = true;
    }

}

class Consumer
{
    public void Consume(IEnumerable<CSVModel> data)
    {
        foreach(var item in data)
        {
             //Do whatever you want with the data. I am gonna log it to the console
             Console.WriteLine(item);
        }
    }
}

public static void Main()
{
    using var myReader = new Reader("c:\\path.csv");
    var consumer = new Consumer().Consume(myReader.Read());
}
 类似资料:
  • 当然,这些列表有setter和getter。现在我想实现以用户身份不参加这些事件的可能性。因此,我尝试了以下方法: 我得到的例外情况如下: 尽管我使用了一些方法来确保执行惰性提取:

  • 我有一个数据表的问题-懒加载。我认为问题是在IdiomasBean.java(TableBean.java),如果我把: 我得到了正确的数据表,但是<代码>按排序、筛选和不起作用。 我得到:java。lang.NullPointerException这里是堆栈跟踪: 下面是代码的其余部分: 指数xhtml diomasBean.java 懒散的数据模型。JAVA IdiomasBo.java 习语

  • 我们目前有几个@OneToOne关系,由于已知的惰性加载的限制,它们总是会急切地从反方向获取。 为了启用逆关系的延迟加载,我正在尝试启用构建时字节码检测。 到目前为止我所做的... 这些关系现在不再急切地加载...但是它们也不会延迟加载,它们只是静默地返回null。 我尝试从实体中删除接口和字段,因为我不确定是否需要这样做,在此之后,我在启动时不再获得消息,并且默认情况下返回到急切加载。 我是不是

  • 我正在为列表视图编写一个lazyload代码,在这个代码中,我得到了一个json格式的文本和图像url,并将它们放在列表视图中。 图像和文字都相应地显示为我想要的。 我面临的问题是,当列表向下或向上滚动时,视图的索引会受到干扰。 假设我的列表中有10个元素,图像可以横向预览。最初,我可以看到4个元素的onclick操作运行良好,但当我向下滚动并单击第7个元素时,索引会受到干扰,并导致空指针异常。

  • 问题内容: 我使用Hibernate 5.2.5(如果重要的话,也可以使用kotlin和spring 4.3.5),并且我希望延迟加载类的某些字段。但是问题是所有字段都立即加载,我没有任何特殊的Hibernate设置,也没有使用Hibernate.initialize()。 这就是我的查询方式 TaskRepoImpl: TaskService: 并输出: 请告知我的代码出了什么问题以及如何使Hi

  • 我有一个简单的查询很好地工作了一段时间,现在我将代码中的一些内容改为: (hibernate.cfg.xml) 和以下代码: 提交后,result对象不会加载列表(即从开始) 如果我执行在提交前,它会保持加载状态,而且,如果我使用它工作得很好。(但这不是它应该如何工作(让它在使用时打开并加载),createAlias应该一如既往地正常工作) 看起来DetachedCriteria的createAl