Если вы рекомендуете использовать SqlCommand.Cancel(), приведите рабочий пример!
Мне нужно показать форму ожидания с кнопкой отмены (если пользователь нажмет эту кнопку, запрос должен прекратить выполнение) во время выполнения запроса.
Мое решение: (.net 4)
Я передаю в конструктор формы два параметра:
- задача выполнения запроса
- действие отмены
Ниже приведен код моей формы загрузки:
public partial class LoadingFrm : Form
{
//task for execute query
private Task execute;
//action for cancelling task
private Action cancel;
public LoadingFrm(Task e, Action c)
{
execute = e;
cancel = c;
InitializeComponent();
this.cancelBtn.Click += this.cancelBtn_Click;
this.FormBorderStyle = FormBorderStyle.None;
this.Load += (s, ea) =>
{
//start task
this.execute.Start();
//close form after execution of task
this.execute.ContinueWith((t) =>
{
if (this.InvokeRequired)
{
Invoke((MethodInvoker)this.Close);
}
else this.Close();
});
};
}
//event handler of cancel button
private void cancelBtn_Click(object sender, EventArgs e)
{
cancel();
}
}
Ниже код моего класса ExecuteHelper:
public class ExecuteHelper
{
public static SqlDataReader Execute(SqlCommand command)
{
var cts = new CancellationTokenSource();
var cToken = cts.Token;
cToken.Register(() => { command.Cancel(); });
Task<SqlDataReader> executeQuery = new Task<SqlDataReader>(command.ExecuteReader, cToken);
//create a form with execute task and action for cancel task if user click on button
LoadingFrm _lFrm = new LoadingFrm(executeQuery, () => { cts.Cancel(); });
_lFrm.ShowDialog();
SqlDataReader r = null;
try
{
//(1) here
r = executeQuery.Result;
}
catch (AggregateException ae)
{
}
catch (Exception ex)
{
}
return r;
}
}
Но я не могу остановить выполнение SqlCommand
. Через некоторое время метод, вызывающий ExecuteHelper.Execute(command)
, получает результат (SqlDataReader)
с сервера sql с данными? Почему? Кто-нибудь может помочь? Как я могу отменить выполнение sqlcommand?
И у меня есть еще вопрос. Почему, если я нажму кнопку отмены моей формы, а cts.Cancel() будет вызван //(1) here
, я получу executeQuery.IsCanceled = false
, хотя executeQuery.Status = Faulted.