我创建了一个WinForms应用程序使用.NET 4.0。
首先,我创建了取消按钮LoadingForm,必须停止执行查询。
我想创建一个ExecuteHelper
类和LoadingForm
与取消查询按钮。
public partial class LoadingFrm : DevExpress.XtraEditors.XtraForm
{
private Action _cancel;
public LoadingFrm(Action a)
{
_cancel = a;
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
}
private void simpleButton1_Click(object sender, EventArgs e)
{
this.close();
_cancel();
}
}
然后,我创建一个ExecuteHelper
类:
public class ExecuteHelper
{
private readonly int tOut = 1000;
private LoadingFrm _loadFrm;
private SqlDataReader _result;
private Task worker;
private CancellationTokenSource cts;
private IAsyncResult iAr;
private SqlCommand _command;
ExecuteHelper()
{
_loadFrm = new LoadingFrm(CancelExecution);
}
public SqlDataReader Execute(SqlCommand command)
{
_command = command;
cts = new CancellationTokenSource();
var cToken = cts.Token;
cts.Token.Register(() => _loadFrm.Invoke((MethodInvoker)delegate() { _loadFrm.Close(); }));
worker = new Task(() => { _loadFrm.ShowDialog(); }, cToken);
SqlDataReader r = null;
worker.Start();
iAr = command.BeginExecuteReader();
while (!iAr.IsCompleted)
{
}
r = command.EndExecuteReader(iAr);
cts.Cancel();
return r;
}
public void CancelExecution()
{
_command.EndExecuteReader(iAr);
}
}
什么是错的,它不显示预期的效果。 任何人都可以帮忙吗?
也许这个解决方案是正确的:
public static SqlDataReader Execute(SqlCommand command)
{
var cts = new CancellationTokenSource();
var cToken = cts.Token;
cToken.Register(() => { command.Cancel(); });
Task<SqlDataReader> query = new Task<SqlDataReader>(new Func<SqlDataReader>(() => { return command.ExecuteReader(); }), cToken);
LoadingFrm _loadingF = new LoadingFrm(() => { cts.Cancel(); });
new Action(() => { _loadingF.Show(); }).Invoke();
query.Start();
query.Wait(30000, cToken);
query.ContinueWith((obj) =>
{
_loadingF.Invoke((MethodInvoker)delegate
{
_loadingF.Close();
});
});
return query.Result;
}
柏迪query.start()
阻塞主线程,我不能装载形式按一下按钮,取消查询执行。