进度条不工作按钮单击C#windows应用程序

时间:2015-01-15 13:00:21

标签: c# progress-bar backgroundworker

我想同步我的本地和Web数据库,所以我使用链接服务器编写了一个存储过程。我的存储过程执行正常,数据同步成功但过程大约需要7-10分钟才能执行。确切的时间无法确定。因此,只要程序在我的Windows应用程序上运行,那么该页面似乎已经变得没有响应,尽管该过程仍在继续。 所以我点击我的页面上有一个“数据同步”按钮,我希望进度条显示存储过程的进度。目前,我采用最后几个执行时序的平均值来定义存储过程运行的持续时间。现在的问题是,当我点击数据同步按钮时,进度条不起作用。请帮我解决这个问题。

我的代码如下: -

namespace RMS
{
    public partial class DataSync : Form
    {
        connection con = new connection();
        SqlCommand cmd = new SqlCommand();

    static int rowCount;
    static int syncTime;
    static int timeSlice;

    public DataSync()
    {
        InitializeComponent();
    }

    private void btnDataSync_Click(object sender, EventArgs e)
    {
            // Start the asynchronous operation.
           backgroundWorker1.RunWorkerAsync();

        try
        {

            con.GetConnectLive();
            con.GetConnect();

            if (con.CnLive.State == ConnectionState.Open)
            {
                MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");

                btnDataSync.Enabled = false;
               btnDataSync.Text = "Please Wait...";

                string Str = "RMS_LocalToLive";
                cmd = new SqlCommand(Str, con.Cn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandTimeout = 1200;

                rowCount = cmd.ExecuteNonQuery();


                if (rowCount > -1)
                {
                    MessageBox.Show("Total no. of rows synchronised = " + rowCount);
                    btnDataSync.Text = "Success";
                }
                else
                {
                   MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
                }

            }
            else
            {
               MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
            }


            con.GetDisConnect();
            con.GetDisConnectLive();
        }
        catch (Exception ex)
        {
           MessageBox.Show("Please check your internet connection and try again!!!");
        }

    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            con.GetConnect();

            string Str = "RMS_DataSyncTime";
            cmd = new SqlCommand(Str, con.Cn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandTimeout = 1200;

            syncTime = Convert.ToInt32(cmd.ExecuteScalar().ToString());

            timeSlice = syncTime / 100;

            con.GetDisConnect();


        }
        catch (Exception ex)
        {
            MessageBox.Show("Unable to retrieve last Data Synchronisation Timing");
        }

        for (int i = 1; i <= synctime; i=i+timeslice)
        {

        Thread.Sleep(timeslice);  
        // Report progress.
         backgroundWorker1.ReportProgress(i);
        }


    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // Change the value of the ProgressBar to the BackgroundWorker progress.
        progressBar1.Value = e.ProgressPercentage;
        // Set the text.
        this.Text = e.ProgressPercentage.ToString() + "% Completed";
    }

    private void DataSync_Load(object sender, EventArgs e)
    {

    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgse)
    {

    }
}

}

1 个答案:

答案 0 :(得分:0)

这里的主要问题是,当您在BackgroundWorker的线程中执行进度条更新时,ReportProgress()更新永远不会进入UI线程,因为您&# 39;用主SQL操作阻止了该线程。

而不是这样做,你应该做更多这样的事情:

private void btnDataSync_Click(object sender, EventArgs e)
{
    // Start the asynchronous operation.
    backgroundWorker1.RunWorkerAsync();

    btnDataSync.Enabled = false;
    btnDataSync.Text = "Please Wait...";

    bool success = false;

    try
    {
        // Execute the query asynchronously
        success = await Task.Run(() => ExecuteLocalToLive());
    }
    catch (Exception ex)
    {
       MessageBox.Show("Please check your internet connection and try again!!!");
    }

    btnDataSync.Enabled = true;
    btnDataSync.Text = success ? "Success" : "Failure";
}

private bool ExecuteLocalToLive()
{
    bool success = false;

    con.GetConnectLive();
    con.GetConnect();

    if (con.CnLive.State == ConnectionState.Open)
    {
        MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");

        string Str = "RMS_LocalToLive";
        cmd = new SqlCommand(Str, con.Cn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandTimeout = 1200;

        rowCount = cmd.ExecuteNonQuery();

        if (rowCount > -1)
        {
            MessageBox.Show("Total no. of rows synchronised = " + rowCount);
            success = true;
        }
        else
        {
           MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
        }
    }
    else
    {
       MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
    }

    con.GetDisConnect();
    con.GetDisConnectLive();

    return success;
}

我重新安排了处理按钮状态和文本的代码,以便它仍然在它所属的UI线程中执行,即使方法本身不是。您似乎也从未将按钮设置回启用状态;我不清楚这是否是故意的,所以我继续前进并增加了一条线来做到这一点。

最后,我强烈建议您找出向用户报告状态的更好方法,而不是现在对MessageBox.Show()的调用。最大的问题是,在用户解除初始消息之后,您甚至不会开始做任何工作,这会立即使您的进度条与实际工作不同步。但是,最好将所有UI保留在UI线程中,并将UI与非UI逻辑(即SQL操作)分开。