2012-01-25 19 views
6

Có thể dừng trình đọc đang chạy?Tôi có thể ngắt trình đọc dữ liệu trong khi đọc không?

Kịch bản: Tôi có một bảng với 100000 bộ dữ liệu

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

và một ứng dụng giao diện điều khiển (.NET 4.0, Npgsql 2.0.11.0/2.0.11.92) cho dữ liệu đọc

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

tôi đã quan sát đầu đọc dữ liệu có thể không thực sự dừng lại. Có vẻ như đầu đọc dữ liệu đọc tất cả các hàng đầu tiên và trả về bình thường sau đó.

Ví dụ này là bản tóm tắt của ứng dụng lớn hơn nơi người dùng sẽ dừng trình đọc dữ liệu bằng cách nhấn nút vì việc đọc mất quá nhiều thời gian.

Trả lời

0

Bạn có thể đặt dấu ngắt trong vòng lặp while, nhưng không chắc chắn liệu/bạn có thể kết hợp điều đó với hành động của người dùng để cho phép họ quyết định thời điểm thoát khỏi vòng lặp đọc hay không. Hoặc bạn có thể cấu trúc lại mã để nó trả về số x hàng đầu tiên và sau đó cung cấp cho họ nút tiếp tục để trả về phần còn lại hoặc trả về số hàng x tiếp theo.

0

Đây là phỏng đoán.

giải pháp có thể xảy ra 1

... 
using (var ta = conn.BeginTransaction(IsolationLevel.Snapshot)) 
{ 
    IDbCommand command = conn.CreateCommand("SELECT * from stock;"); 
    command.SetTransaction(ta); 
    IDataReader reader = command.ExecuteReader(); 

    int n = 5000; 

    //put it in using 
    using(IDataReader reader = command.ExecuteReader()) 
    { 
     //read first N rows 
     for(int i=0;i<n;i++) 
     {   
      //get value from the columns of the current row 
      for (i = 0; i < reader.FieldCount; i++) 
      { 
       Console.Write("{0} \t", reader[i]); 
      } 
     } 
    }  
} 

thể sollution 2

Sử dụng TOP sql lệnh, see samples

+0

Tôi đã để lại kết quả đầu ra nhật ký trong trường hợp của mình.Đăng xuất kết quả đầu ra để kiểm tra hành vi của trình đọc dữ liệu trong kịch bản của tôi hiển thị luôn luôn là một thời gian chờ đợi sau khi lệnh "((NpgsqlDataReader) đọc) .Đóng()" của một số giây. Thời gian chờ đợi này là như nhau nếu tôi đọc hết tất cả các hàng. – Joerg

+0

! True && false đánh giá sai. XOR sai đúng sẽ đánh giá đúng. –

+0

đúng, sẽ cập nhật điều này. – oleksii

0

Người đọc dữ liệu thường trả về khối dữ liệu từ máy chủ cơ sở dữ liệu (ít nhất đó là cách nó hoạt động với SQL Server). Postgre SQL có thể hoạt động khác nhau dưới các trang bìa.

Một cách khác để tấn công điều này là tải dữ liệu dưới dạng tác vụ nền (BackgroundWorker, Task, v.v ...). Bằng cách đó, chuỗi giao diện người dùng của bạn vẫn đáp ứng và không quan trọng cách trình đọc được triển khai trong trang bìa.

+0

Tôi không nghĩ rằng một BackgroundWorker sẽ làm việc trong một ứng dụng giao diện điều khiển. – LarsTech

+0

Tôi đã thực hiện nó. Nhưng đôi khi người dùng muốn bắt đầu một truy vấn mới với dữ liệu khác nhau trong khi đọc và hiển thị các hàng dữ liệu đầu tiên. Và bây giờ tôi phải dừng trình đọc dữ liệu và bắt đầu một lệnh resp mới. đầu đọc dữ liệu. – Joerg

6

Tôi biết chủ đề này là khá cũ, nhưng tôi tin rằng câu trả lời đúng cho câu hỏi của người này là như sau:

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

Bằng cách gọi DbCommand.Cancel(), bạn đang chứng tỏ rằng không có hồ sơ hơn nữa nên được xử lý và lệnh (bao gồm cả truy vấn cơ bản) nên tạm dừng và thoát ra nhanh chóng. Nếu bạn không hủy lệnh, khi bạn cố gắng đóng DbDataReader (hoặc thoát khỏi vòng lặp/sử dụng khối) và bạn đang xử lý một số lượng lớn các bản ghi được trả về, phương thức Close() sẽ điền vào giá trị cho tham số đầu ra, giá trị trả về và RecordsAffected.

Nếu bạn cố gắng đóng trình đọc trước khi đọc tất cả các bản ghi, Đóng cố gắng đọc tất cả dữ liệu và điền vào các giá trị đó, và dường như sẽ treo (rất có thể dẫn đến một số loại trừ thời gian chờ ném). Nếu bạn không quan tâm đến các giá trị còn lại trong tập hợp kết quả - và bạn có thể không nhất thiết nếu bạn không tham gia vòng lặp đọc - bạn nên hủy lệnh cơ bản trước khi gọi Close().

Các phần của thông tin trên đã được truy lục từ: https://www.informit.com/guides/content.aspx?g=dotnet&seqNum=610

+0

Đây là câu trả lời –

Các vấn đề liên quan