如何在执行长时间查询时显示加载对话框?

时间:2014-07-01 09:18:19

标签: c# .net asynchronous task sqlcommand

我使用.net 4.0创建了一个winforms应用程序。

首先,我创建了一个带取消按钮的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;
}

Bur query.start()阻止了主线程,我无法点击加载表单中的按钮来执行取消查询。

0 个答案:

没有答案