c# - 我可以在读取过程中中断数据读取器吗?

标签 c# ado.net npgsql

有可能停止正在运行的阅读器吗?

场景:我有一个表有100000个数据集

CREATE TABLE stock (
uid bigint NOT NULL,
name text,
quantity integer,
x bytea,
y bytea
);

和一个用于读取数据的控制台应用程序(.NET 4.0、Npgsql 2.0.11.0/2.0.11.92)

conn = new NpgsqlConnection("Server=localhost;Database=postgres;User id=postgres;password=postgres;Timeout=600;CommandTimeout=600;ConnectionLifeTime=600;");
using (new ConnectionOpen(conn))
using (var ta = conn.BeginTransaction(IsolationLevel.Snapshot))
{
    IDbCommand command = conn.CreateCommand("SELECT * from stock;");
    command.SetTransaction(ta);
    IDataReader reader = command.ExecuteReader();

    int n = 0;
    while (!reader.IsClosed && reader.Read())
    {
        n++;

        if (n > 5000)
        {
            if (reader != null)
            {
                 ((NpgsqlDataReader)reader).Close();
            }
        }
     }
     ((NpgsqlDataReader)reader).Dispose();
     reader = null;
}

我观察到数据读取器无法真正停止。数据读取器似乎先读取所有行,然后正常返回。

这个例子是一个更大的应用程序的抽象,在这个应用程序中,用户将通过按下按钮来停止数据读取器,因为读取时间太长。

最佳答案

我知道这个帖子很旧,但我相信这个人的问题的正确答案如下:

command.Cancel(); //execute before closing the reader
reader.Close();

通过调用 DbCommand.Cancel(),您表示不应处理更多记录并且命令(包括基础查询)应立即停止并快速退出。如果您不取消命令,当您尝试关闭 DbDataReader(或跳出循环/使用 block )并且您正在处理大量返回的记录时,Close() 方法将填充输出参数、返回值和 RecordsAffected 的值。

如果您尝试在读取器读取所有记录之前关闭读取器,Close 会尝试读取所有数据并填写这些值,它似乎只是挂起(很可能导致抛出某种超时异常).如果您不关心结果集中剩余的值——如果您要跳出读取循环,您很可能不关心——您应该在调用 Close() 之前取消底层命令。

以上部分信息取自:https://www.informit.com/guides/content.aspx?g=dotnet&seqNum=610

关于c# - 我可以在读取过程中中断数据读取器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9005692/

相关文章:

c# - 插入前验证数据的最佳方法

c# - SET READ_COMMITTED_SNAPSHOT ON 的 ADO.Net IsolationLevel.Snapshot

PostgreSQL,获取数据库存在于 Npgsql

c# - OwnsOne 从表键中删除 IDENTITY

c# - Npgsql 如何处理失败的事务?

c# - WinForms Livecharts 图表标题

c# - 如何在Entity Framework -6的onmodelcreating方法中映射与模型不同的表名和列名?

c# - 向我解释这个 SELECT dbo.TableName(@variable) 语句

c# - 变量名 '@Param'已经被声明

c# - 带有 IDataReader 的 AutoMapper 到 List 总是返回 0 计数