SqlCommand.Cancel question

  • Thread starter Thread starter Sergey Ivasenko
  • Start date Start date
S

Sergey Ivasenko

I open an SqlConnection.
Then:
1. execute a reader on SqlCommand and get data through that reader;
2. in a certain time I call Cancel() method on SqlCommand and
SqlDataReader.Close().

If I perform steps 1 and 2 several times (sometimes it happens even from the
first time)
I get the error which says that SqlConnection is closed. And it is. So,
seems that SqlCommand.Cancel()
in combination with SqlDataReader.Close() forces the connection to close.
I can't determine the reason why it happens.
Can I control somehow this behaviour, because I need the connection to be
opened.

Thank you in advance,
Sergey Ivasenko.
 
Sergey, I am sorry for security reasons we do not look at post attachments,
could you post it as text.
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Sergey Ivasenko said:
Here is the repro code (see attach).

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

Angel Saenz-Badillos said:
can you post some code? I will look into this.

Thanks,
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Sergey Ivasenko said:
I open an SqlConnection.
Then:
1. execute a reader on SqlCommand and get data through that reader;
2. in a certain time I call Cancel() method on SqlCommand and
SqlDataReader.Close().

If I perform steps 1 and 2 several times (sometimes it happens even
from
the
first time)
I get the error which says that SqlConnection is closed. And it is. So,
seems that SqlCommand.Cancel()
in combination with SqlDataReader.Close() forces the connection to close.
I can't determine the reason why it happens.
Can I control somehow this behaviour, because I need the connection to be
opened.

Thank you in advance,
Sergey Ivasenko.
 
Simple winform, that has two buttons: Start and Cancel a a Label component
for record count display.

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

---------------------------------
CUT ---------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.Net;
namespace WindowsApplication8
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStart; // Start button
private System.Windows.Forms.Button btnCancel; // Cancel button
private System.Windows.Forms.Label lbRecCount; // Record count label
private System.ComponentModel.Container components = null;
SqlCommand _localCmd;
SqlConnection _con;
bool _canceled = false;
DataSet _dataSet;
public Form1()
{
InitializeComponent();
_dataSet = new DataSet();
_con = new SqlConnection("data source=YOUR_SOURCE;initial
catalog=YOUR_CATALOG;password=PWD;persist security info=True;user
id=LOGIN;workstation id=" + Dns.GetHostName() + ";application name=" +
Application.ProductName + ";packet size=4096;Pooling=false");
_con.Open();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
_con.Close();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStart = new System.Windows.Forms.Button();
this.lbRecCount = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(20, 48);
this.btnStart.Name = "btnStart";
this.btnStart.TabIndex = 0;
this.btnStart.Text = "Start";
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// lbRecCount
//
this.lbRecCount.AutoSize = true;
this.lbRecCount.Location = new System.Drawing.Point(87, 12);
this.lbRecCount.Name = "lbRecCount";
this.lbRecCount.Size = new System.Drawing.Size(35, 16);
this.lbRecCount.TabIndex = 1;
this.lbRecCount.Text = "label1";
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(113, 48);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(208, 93);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.lbRecCount);
this.Controls.Add(this.btnStart);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnStart_Click(object sender, System.EventArgs e)
{
Start();
}
void Start()
{
SqlDataReader reader = null;
Exception exc = null;
lock(this)
{
try
{
// set some store proc to execute
// this proc should return a record set
_localCmd = new SqlCommand("YOUR_STORED_PROC", _con);
_localCmd.CommandType = CommandType.StoredProcedure;
_localCmd.CommandTimeout = 120;
SqlCommandBuilder.DeriveParameters(_localCmd);
_dataSet.Tables.Clear();
// executing a command
reader = _localCmd.ExecuteReader();
int tableIndex = 0;
bool has_rows = true;
DataTable table = null;
object[] row = null;
// starting from here (see much code) is just simple reading of
// rows with data reader and adding then to _dataSet.Tables
while(has_rows && !_canceled)
{
has_rows = reader.Read();
if(_dataSet.Tables.Count <= tableIndex)
{
table = _dataSet.Tables.Add();
for(int i = 0; i < reader.FieldCount; i++)
table.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
else
table = _dataSet.Tables[tableIndex];
if(has_rows)
{
row = new object[reader.FieldCount];
reader.GetValues(row);
table.Rows.Add(row);
}
else
{
has_rows = reader.NextResult();
if(has_rows)
tableIndex++;
}
if(TotalRecCount % 1000 == 0)
DisplayRecCount(TotalRecCount);
} // while
}
catch(Exception err)
{
exc = err;
}
if(reader != null)
{
try
{
if(_canceled)
CancelCommand();
reader.Close();
}
catch(Exception)
{}
}
_canceled = false;
if(exc != null)
MessageBox.Show(exc.Message, "Error");
}
}
public void CancelSelect()
{
_canceled = true;
}
/// <summary>
/// Cancels data reading
/// </summary>
void CancelCommand()
{
_localCmd.Cancel();
MessageBox.Show("Command canceled!", "");
}
private void btnCancel_Click(object sender, System.EventArgs e)
{
CancelSelect();
}
void DisplayRecCount(int recCount)
{
lbRecCount.Text = recCount.ToString();
lbRecCount.Refresh();
Application.DoEvents();
}

/// <summary>
/// Total record count.
/// </summary>
public int TotalRecCount
{
get
{
int recCount = 0;
foreach(DataTable table in _dataSet.Tables)
recCount += table.Rows.Count;
return recCount;
}
}
}
}
---------------------------------
CUT ---------------------------------------------
Angel Saenz-Badillos said:
Sergey, I am sorry for security reasons we do not look at post attachments,
could you post it as text.
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Sergey Ivasenko said:
Here is the repro code (see attach).

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

can you post some code? I will look into this.

Thanks,
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

I open an SqlConnection.
Then:
1. execute a reader on SqlCommand and get data through that reader;
2. in a certain time I call Cancel() method on SqlCommand and
SqlDataReader.Close().

If I perform steps 1 and 2 several times (sometimes it happens even from
the
first time)
I get the error which says that SqlConnection is closed. And it is. So,
seems that SqlCommand.Cancel()
in combination with SqlDataReader.Close() forces the connection to close.
I can't determine the reason why it happens.
Can I control somehow this behaviour, because I need the connection
to
be
opened.

Thank you in advance,
Sergey Ivasenko.
 
I have not yet been able to repro this problem, I am going to build a bigger
table (I only had about 20k)

The schema of the table I am generating is as follows:
create table Adapter_ANGELSA_094028116_10222003 (col_int_1 int PRIMARY KEY ,
col_int_2 int not null , col_numeric_3 numeric(9,0) identity not null ,
col_smallint_4 smallint DEFAULT (3), col_real_5 real, col_float_6 float,
col_money_7 money, col_smallmoney_8 smallmoney, col_bit_9 bit,
col_tinyint_10 tinyint, col_uniqueidentifier_11 uniqueidentifier,
col_varbinary_12 varbinary(756), col_binary_13 binary(756), col_image_14
image, col_timestamp_15 timestamp, col_char_16 char(756), col_text_17 text,
col_varchar_18 varchar(756), col_nchar_19 nchar(756), col_ntext_20 ntext,
col_nvarchar_21 nvarchar(756), col_datetime_22 datetime,
col_smalldatetime_23 smalldatetime, col_decimal_24 decimal(28,4),
col_bigint_25 bigint, col_sql_variant_26 sql_variant )

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.


Sergey Ivasenko said:
Simple winform, that has two buttons: Start and Cancel a a Label component
for record count display.

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

---------------------------------
CUT ---------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.Net;
namespace WindowsApplication8
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStart; // Start button
private System.Windows.Forms.Button btnCancel; // Cancel button
private System.Windows.Forms.Label lbRecCount; // Record count label
private System.ComponentModel.Container components = null;
SqlCommand _localCmd;
SqlConnection _con;
bool _canceled = false;
DataSet _dataSet;
public Form1()
{
InitializeComponent();
_dataSet = new DataSet();
_con = new SqlConnection("data source=YOUR_SOURCE;initial
catalog=YOUR_CATALOG;password=PWD;persist security info=True;user
id=LOGIN;workstation id=" + Dns.GetHostName() + ";application name=" +
Application.ProductName + ";packet size=4096;Pooling=false");
_con.Open();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
_con.Close();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStart = new System.Windows.Forms.Button();
this.lbRecCount = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(20, 48);
this.btnStart.Name = "btnStart";
this.btnStart.TabIndex = 0;
this.btnStart.Text = "Start";
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// lbRecCount
//
this.lbRecCount.AutoSize = true;
this.lbRecCount.Location = new System.Drawing.Point(87, 12);
this.lbRecCount.Name = "lbRecCount";
this.lbRecCount.Size = new System.Drawing.Size(35, 16);
this.lbRecCount.TabIndex = 1;
this.lbRecCount.Text = "label1";
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(113, 48);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(208, 93);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.lbRecCount);
this.Controls.Add(this.btnStart);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnStart_Click(object sender, System.EventArgs e)
{
Start();
}
void Start()
{
SqlDataReader reader = null;
Exception exc = null;
lock(this)
{
try
{
// set some store proc to execute
// this proc should return a record set
_localCmd = new SqlCommand("YOUR_STORED_PROC", _con);
_localCmd.CommandType = CommandType.StoredProcedure;
_localCmd.CommandTimeout = 120;
SqlCommandBuilder.DeriveParameters(_localCmd);
_dataSet.Tables.Clear();
// executing a command
reader = _localCmd.ExecuteReader();
int tableIndex = 0;
bool has_rows = true;
DataTable table = null;
object[] row = null;
// starting from here (see much code) is just simple reading of
// rows with data reader and adding then to _dataSet.Tables
while(has_rows && !_canceled)
{
has_rows = reader.Read();
if(_dataSet.Tables.Count <= tableIndex)
{
table = _dataSet.Tables.Add();
for(int i = 0; i < reader.FieldCount; i++)
table.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
else
table = _dataSet.Tables[tableIndex];
if(has_rows)
{
row = new object[reader.FieldCount];
reader.GetValues(row);
table.Rows.Add(row);
}
else
{
has_rows = reader.NextResult();
if(has_rows)
tableIndex++;
}
if(TotalRecCount % 1000 == 0)
DisplayRecCount(TotalRecCount);
} // while
}
catch(Exception err)
{
exc = err;
}
if(reader != null)
{
try
{
if(_canceled)
CancelCommand();
reader.Close();
}
catch(Exception)
{}
}
_canceled = false;
if(exc != null)
MessageBox.Show(exc.Message, "Error");
}
}
public void CancelSelect()
{
_canceled = true;
}
/// <summary>
/// Cancels data reading
/// </summary>
void CancelCommand()
{
_localCmd.Cancel();
MessageBox.Show("Command canceled!", "");
}
private void btnCancel_Click(object sender, System.EventArgs e)
{
CancelSelect();
}
void DisplayRecCount(int recCount)
{
lbRecCount.Text = recCount.ToString();
lbRecCount.Refresh();
Application.DoEvents();
}

/// <summary>
/// Total record count.
/// </summary>
public int TotalRecCount
{
get
{
int recCount = 0;
foreach(DataTable table in _dataSet.Tables)
recCount += table.Rows.Count;
return recCount;
}
}
}
}
---------------------------------
CUT ---------------------------------------------
Angel Saenz-Badillos said:
Sergey, I am sorry for security reasons we do not look at post attachments,
could you post it as text.
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Sergey Ivasenko said:
Here is the repro code (see attach).

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

can you post some code? I will look into this.

Thanks,
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.
Please do not send email directly to this alias. This alias is for
newsgroup
purposes only.

I open an SqlConnection.
Then:
1. execute a reader on SqlCommand and get data through that reader;
2. in a certain time I call Cancel() method on SqlCommand and
SqlDataReader.Close().

If I perform steps 1 and 2 several times (sometimes it happens
even
from
the
first time)
I get the error which says that SqlConnection is closed. And it
is.
So,
seems that SqlCommand.Cancel()
in combination with SqlDataReader.Close() forces the connection to
close.
I can't determine the reason why it happens.
Can I control somehow this behaviour, because I need the
connection
 
I have tried to run this repro with 400k records and have not been able to
repro.

Could you post some more information about your setup? table schema, mdac
version installed, os and version of server you are connecting to for
example?
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Angel Saenz-Badillos said:
I have not yet been able to repro this problem, I am going to build a bigger
table (I only had about 20k)

The schema of the table I am generating is as follows:
create table Adapter_ANGELSA_094028116_10222003 (col_int_1 int PRIMARY KEY ,
col_int_2 int not null , col_numeric_3 numeric(9,0) identity not null ,
col_smallint_4 smallint DEFAULT (3), col_real_5 real, col_float_6 float,
col_money_7 money, col_smallmoney_8 smallmoney, col_bit_9 bit,
col_tinyint_10 tinyint, col_uniqueidentifier_11 uniqueidentifier,
col_varbinary_12 varbinary(756), col_binary_13 binary(756), col_image_14
image, col_timestamp_15 timestamp, col_char_16 char(756), col_text_17 text,
col_varchar_18 varchar(756), col_nchar_19 nchar(756), col_ntext_20 ntext,
col_nvarchar_21 nvarchar(756), col_datetime_22 datetime,
col_smalldatetime_23 smalldatetime, col_decimal_24 decimal(28,4),
col_bigint_25 bigint, col_sql_variant_26 sql_variant )

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.


Sergey Ivasenko said:
Simple winform, that has two buttons: Start and Cancel a a Label component
for record count display.

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

---------------------------------
CUT ---------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.Net;
namespace WindowsApplication8
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStart; // Start button
private System.Windows.Forms.Button btnCancel; // Cancel button
private System.Windows.Forms.Label lbRecCount; // Record count label
private System.ComponentModel.Container components = null;
SqlCommand _localCmd;
SqlConnection _con;
bool _canceled = false;
DataSet _dataSet;
public Form1()
{
InitializeComponent();
_dataSet = new DataSet();
_con = new SqlConnection("data source=YOUR_SOURCE;initial
catalog=YOUR_CATALOG;password=PWD;persist security info=True;user
id=LOGIN;workstation id=" + Dns.GetHostName() + ";application name=" +
Application.ProductName + ";packet size=4096;Pooling=false");
_con.Open();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
_con.Close();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStart = new System.Windows.Forms.Button();
this.lbRecCount = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(20, 48);
this.btnStart.Name = "btnStart";
this.btnStart.TabIndex = 0;
this.btnStart.Text = "Start";
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// lbRecCount
//
this.lbRecCount.AutoSize = true;
this.lbRecCount.Location = new System.Drawing.Point(87, 12);
this.lbRecCount.Name = "lbRecCount";
this.lbRecCount.Size = new System.Drawing.Size(35, 16);
this.lbRecCount.TabIndex = 1;
this.lbRecCount.Text = "label1";
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(113, 48);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(208, 93);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.lbRecCount);
this.Controls.Add(this.btnStart);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnStart_Click(object sender, System.EventArgs e)
{
Start();
}
void Start()
{
SqlDataReader reader = null;
Exception exc = null;
lock(this)
{
try
{
// set some store proc to execute
// this proc should return a record set
_localCmd = new SqlCommand("YOUR_STORED_PROC", _con);
_localCmd.CommandType = CommandType.StoredProcedure;
_localCmd.CommandTimeout = 120;
SqlCommandBuilder.DeriveParameters(_localCmd);
_dataSet.Tables.Clear();
// executing a command
reader = _localCmd.ExecuteReader();
int tableIndex = 0;
bool has_rows = true;
DataTable table = null;
object[] row = null;
// starting from here (see much code) is just simple reading of
// rows with data reader and adding then to _dataSet.Tables
while(has_rows && !_canceled)
{
has_rows = reader.Read();
if(_dataSet.Tables.Count <= tableIndex)
{
table = _dataSet.Tables.Add();
for(int i = 0; i < reader.FieldCount; i++)
table.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
else
table = _dataSet.Tables[tableIndex];
if(has_rows)
{
row = new object[reader.FieldCount];
reader.GetValues(row);
table.Rows.Add(row);
}
else
{
has_rows = reader.NextResult();
if(has_rows)
tableIndex++;
}
if(TotalRecCount % 1000 == 0)
DisplayRecCount(TotalRecCount);
} // while
}
catch(Exception err)
{
exc = err;
}
if(reader != null)
{
try
{
if(_canceled)
CancelCommand();
reader.Close();
}
catch(Exception)
{}
}
_canceled = false;
if(exc != null)
MessageBox.Show(exc.Message, "Error");
}
}
public void CancelSelect()
{
_canceled = true;
}
/// <summary>
/// Cancels data reading
/// </summary>
void CancelCommand()
{
_localCmd.Cancel();
MessageBox.Show("Command canceled!", "");
}
private void btnCancel_Click(object sender, System.EventArgs e)
{
CancelSelect();
}
void DisplayRecCount(int recCount)
{
lbRecCount.Text = recCount.ToString();
lbRecCount.Refresh();
Application.DoEvents();
}

/// <summary>
/// Total record count.
/// </summary>
public int TotalRecCount
{
get
{
int recCount = 0;
foreach(DataTable table in _dataSet.Tables)
recCount += table.Rows.Count;
return recCount;
}
}
}
}
---------------------------------
CUT ---------------------------------------------
Sergey, I am sorry for security reasons we do not look at post attachments,
could you post it as text.
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Here is the repro code (see attach).

TODO
- set your connection string and stored proc to execute; stored proc
should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

can you post some code? I will look into this.

Thanks,
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.
Please do not send email directly to this alias. This alias is for
newsgroup
purposes only.

I open an SqlConnection.
Then:
1. execute a reader on SqlCommand and get data through that reader;
2. in a certain time I call Cancel() method on SqlCommand and
SqlDataReader.Close().

If I perform steps 1 and 2 several times (sometimes it happens even
from
the
first time)
I get the error which says that SqlConnection is closed. And it is.
So,
seems that SqlCommand.Cancel()
in combination with SqlDataReader.Close() forces the connection to
close.
I can't determine the reason why it happens.
Can I control somehow this behaviour, because I need the
connection
to
be
opened.

Thank you in advance,
Sergey Ivasenko.
 
I'm really frustrated that you couldn't repro the problem and happy that you
didn't experience such a problem:)
I don't know what to do...
I think it doesn't matter, because I get data from stored proc, but anyway,
it's a selection of
WareId int,
WareNum varchar(22),
WareName varchar(70)

- Framework 1.1
- MDAC ver 2.71
- MS SQL Server 2000 Enterprise Edition
- MS Windows 2000 Advanced Server (both client and SQL server hosts)
- MS VS 2003

Thank you in advance,
Sergey.

Angel Saenz-Badillos said:
I have tried to run this repro with 400k records and have not been able to
repro.

Could you post some more information about your setup? table schema, mdac
version installed, os and version of server you are connecting to for
example?
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

Angel Saenz-Badillos said:
I have not yet been able to repro this problem, I am going to build a bigger
table (I only had about 20k)

The schema of the table I am generating is as follows:
create table Adapter_ANGELSA_094028116_10222003 (col_int_1 int PRIMARY
KEY
,
col_int_2 int not null , col_numeric_3 numeric(9,0) identity not null ,
col_smallint_4 smallint DEFAULT (3), col_real_5 real, col_float_6 float,
col_money_7 money, col_smallmoney_8 smallmoney, col_bit_9 bit,
col_tinyint_10 tinyint, col_uniqueidentifier_11 uniqueidentifier,
col_varbinary_12 varbinary(756), col_binary_13 binary(756), col_image_14
image, col_timestamp_15 timestamp, col_char_16 char(756), col_text_17 text,
col_varchar_18 varchar(756), col_nchar_19 nchar(756), col_ntext_20 ntext,
col_nvarchar_21 nvarchar(756), col_datetime_22 datetime,
col_smalldatetime_23 smalldatetime, col_decimal_24 decimal(28,4),
col_bigint_25 bigint, col_sql_variant_26 sql_variant )

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.


Sergey Ivasenko said:
Simple winform, that has two buttons: Start and Cancel a a Label component
for record count display.

TODO
- set your connection string and stored proc to execute; stored proc should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

---------------------------------
CUT ---------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.Net;
namespace WindowsApplication8
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStart; // Start button
private System.Windows.Forms.Button btnCancel; // Cancel button
private System.Windows.Forms.Label lbRecCount; // Record count label
private System.ComponentModel.Container components = null;
SqlCommand _localCmd;
SqlConnection _con;
bool _canceled = false;
DataSet _dataSet;
public Form1()
{
InitializeComponent();
_dataSet = new DataSet();
_con = new SqlConnection("data source=YOUR_SOURCE;initial
catalog=YOUR_CATALOG;password=PWD;persist security info=True;user
id=LOGIN;workstation id=" + Dns.GetHostName() + ";application name=" +
Application.ProductName + ";packet size=4096;Pooling=false");
_con.Open();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
_con.Close();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStart = new System.Windows.Forms.Button();
this.lbRecCount = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(20, 48);
this.btnStart.Name = "btnStart";
this.btnStart.TabIndex = 0;
this.btnStart.Text = "Start";
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// lbRecCount
//
this.lbRecCount.AutoSize = true;
this.lbRecCount.Location = new System.Drawing.Point(87, 12);
this.lbRecCount.Name = "lbRecCount";
this.lbRecCount.Size = new System.Drawing.Size(35, 16);
this.lbRecCount.TabIndex = 1;
this.lbRecCount.Text = "label1";
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(113, 48);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(208, 93);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.lbRecCount);
this.Controls.Add(this.btnStart);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnStart_Click(object sender, System.EventArgs e)
{
Start();
}
void Start()
{
SqlDataReader reader = null;
Exception exc = null;
lock(this)
{
try
{
// set some store proc to execute
// this proc should return a record set
_localCmd = new SqlCommand("YOUR_STORED_PROC", _con);
_localCmd.CommandType = CommandType.StoredProcedure;
_localCmd.CommandTimeout = 120;
SqlCommandBuilder.DeriveParameters(_localCmd);
_dataSet.Tables.Clear();
// executing a command
reader = _localCmd.ExecuteReader();
int tableIndex = 0;
bool has_rows = true;
DataTable table = null;
object[] row = null;
// starting from here (see much code) is just simple reading of
// rows with data reader and adding then to _dataSet.Tables
while(has_rows && !_canceled)
{
has_rows = reader.Read();
if(_dataSet.Tables.Count <= tableIndex)
{
table = _dataSet.Tables.Add();
for(int i = 0; i < reader.FieldCount; i++)
table.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
else
table = _dataSet.Tables[tableIndex];
if(has_rows)
{
row = new object[reader.FieldCount];
reader.GetValues(row);
table.Rows.Add(row);
}
else
{
has_rows = reader.NextResult();
if(has_rows)
tableIndex++;
}
if(TotalRecCount % 1000 == 0)
DisplayRecCount(TotalRecCount);
} // while
}
catch(Exception err)
{
exc = err;
}
if(reader != null)
{
try
{
if(_canceled)
CancelCommand();
reader.Close();
}
catch(Exception)
{}
}
_canceled = false;
if(exc != null)
MessageBox.Show(exc.Message, "Error");
}
}
public void CancelSelect()
{
_canceled = true;
}
/// <summary>
/// Cancels data reading
/// </summary>
void CancelCommand()
{
_localCmd.Cancel();
MessageBox.Show("Command canceled!", "");
}
private void btnCancel_Click(object sender, System.EventArgs e)
{
CancelSelect();
}
void DisplayRecCount(int recCount)
{
lbRecCount.Text = recCount.ToString();
lbRecCount.Refresh();
Application.DoEvents();
}

/// <summary>
/// Total record count.
/// </summary>
public int TotalRecCount
{
get
{
int recCount = 0;
foreach(DataTable table in _dataSet.Tables)
recCount += table.Rows.Count;
return recCount;
}
}
}
}
---------------------------------
CUT ---------------------------------------------
Sergey, I am sorry for security reasons we do not look at post
attachments,
could you post it as text.
Thanks

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.
Please do not send email directly to this alias. This alias is for
newsgroup
purposes only.

Here is the repro code (see attach).

TODO
- set your connection string and stored proc to execute; stored proc
should
just return a larg (~100 000 records) recordset;
- press Start button and then Cancel one;
- press Start button again.

message
can you post some code? I will look into this.

Thanks,
confers
no it
is.
connection
 
Back
Top