我可以在阅读时中断数据读取器吗?

Joe*_*erg 7 c# ado.net npgsql

可以阻止正在运行的读卡器吗?

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

CREATE TABLE stock (
uid bigint NOT NULL,
name text,
quantity integer,
x bytea,
y bytea
);
Run Code Online (Sandbox Code Playgroud)

和一个用于读取数据的控制台应用程序(.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;
}
Run Code Online (Sandbox Code Playgroud)

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

此示例是较大应用程序的摘要,用户将通过按下按钮来停止数据读取器,因为读取时间过长.

Bri*_*ead 9

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

command.Cancel(); //execute before closing the reader
reader.Close();
Run Code Online (Sandbox Code Playgroud)

通过调用DbCommand.Cancel(),您将指示不应处理其他记录,并且该命令(包括基础查询)应立即停止并快速退出.如果你没有取消命令,当你试图关闭DbDataReader(或打破循环/使用块),并且你正在处理返回的大量记录时,Close()方法填写输出参数,返回值和RecordsAffected的值.

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

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


Bri*_*ian 0

您可以在 while 循环中放置一个中断,但不确定是否/如何将其与用户操作联系起来,让他们决定何时跳出读取循环。或者,您可以重组代码,使其返回前 x 行,然后给它们一个继续按钮以返回其余行或返回下 x 行。