0

任何人都可以启发我吗?直到主UI线程完成才更新,为什么会这样?

我的部分代码:

//初始化BW

 private void InitializeBW()
        {
            BW.WorkerReportsProgress = true;
            BW.WorkerSupportsCancellation = true;
            BW.DoWork +=
                 new DoWorkEventHandler(BW_DoWork);
            BW.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(
            BW_RunWorkerCompleted);
            BW.ProgressChanged +=
                new ProgressChangedEventHandler(
            BW_ProgressChanged);

        }

\做工作事件

 private void BW_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
        for (int i = CurrentProcess; i <= Process; i++)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                System.Threading.Thread.Sleep(100);
                worker.ReportProgress(i);
            }
        }
        CurrentProcess = Process;
    }

\更新主界面

 private void BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            pgBar.Value = e.ProgressPercentage;
            lbProgress.Text = (e.ProgressPercentage.ToString() + "%");
            pgBar.Refresh();
            lbProgress.Refresh();
        }

\我的主要用户界面操作

private void btnCreate_Click(object sender, EventArgs e)
        {
            try
            {
                DatabaseParam DBPara = new DatabaseParam();
                isCreate = true;
                EDFields(!isCreate);

                DBPara.ServerName = txtServerName.Text;
                DBPara.DatabaseName = "PARKS_ARCHIVE_" + nudYear.Value.ToString();
                DBPara.ID = txtUserName.Text;
                DBPara.Password = txtPassword.Text;
                DBPara.DataFileName = "PARKS_ARCHIVE_DATA_" + nudYear.Value.ToString();
                DBPara.DataPathName = txtPath.Text + "\\PARKS_ARCHIVE_DATA_" + nudYear.Value.ToString();
                DBPara.DataFileSize = "10MB";
                DBPara.DataFileGrowth = "1024MB";
                DBPara.LogFileName = "PARKS_ARCHIVE_LOG_" + nudYear.Value.ToString();
                DBPara.LogPathName = txtPath.Text + "\\PARKS_ARCHIVE_LOG_" + nudYear.Value.ToString();
                DBPara.LogFileSize = "10MB";
                DBPara.LogFileGrowth = "20MB";

                CreateDatabase(DBPara);
            }
            catch (Exception ex)
            {
                Logger.LogError("ucArchivePurge", "btnCreate_Click", ex.Message);
            }
            finally
            {
            }
        }

//调用创建数据库和表

private void CreateDatabase(DatabaseParam DBParam)
    {
        try
        {
            Process = 7;
            BW = new BackgroundWorker();
            InitializeBW();
            if (BW.IsBusy != true)
            {
                // Start the asynchronous operation.
                BW.RunWorkerAsync();
            }
            System.Threading.Thread.Sleep(800);
            txtProgress.Text = "Creating " + DBParam.DatabaseName + "...";


        SQLConn.Open();
        myCommand = new SqlCommand(sqlCreateDBQuery, SQLConn);
        myCommand.ExecuteNonQuery();
        SQLConn.Close();
        BW.CancelAsync();

        Process = 14;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        System.Threading.Thread.Sleep(800);
        txtProgress.Text = "Creating Table tblAuditLogin...";
        txtProgress.Refresh();

        SQLCreate.Open();
        myCommand.Connection = SQLCreate;
        myCommand.CommandText = CreateAuditLogin;
        myCommand.ExecuteNonQuery();
        BW.CancelAsync();

        Process = 21;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        System.Threading.Thread.Sleep(800);
        txtProgress.Text = "Creating Table tblAuditTrail...";
        txtProgress.Refresh();               
        myCommand.CommandText = CreateAuditTrail;
        myCommand.ExecuteNonQuery();
        BW.CancelAsync();

        Process = 28;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblCardType...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateCardType;
        myCommand.ExecuteNonQuery();

        Process = 35;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblErrorLog...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateErrorLog;
        myCommand.ExecuteNonQuery();

        Process = 42;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblKanban_Card...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTableKanban;
        myCommand.ExecuteNonQuery();

        Process = 49;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblModule_Master...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTableModule;
        myCommand.ExecuteNonQuery();

        Process = 56;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblMTV...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTableMTV;
        myCommand.ExecuteNonQuery();

        Process = 63;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblPickList_Detail...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTablePickDetail;
        myCommand.ExecuteNonQuery();

        Process = 70;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblPickList_Header...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreatePickHeader;
        myCommand.ExecuteNonQuery();

        Process = 77;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblProd_Requisition...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTableProduction;
        myCommand.ExecuteNonQuery();

        Process = 84;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblUser_Master...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTableUser;
        myCommand.ExecuteNonQuery();

        Process = 91;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Creating Table tblUser_Rights...";
        txtProgress.Refresh();
        System.Threading.Thread.Sleep(800);
        myCommand.CommandText = CreateTableRight;
        myCommand.ExecuteNonQuery();
        SQLCreate.Close();

        Process = 100;
        BW = new BackgroundWorker();
        InitializeBW();
        if (BW.IsBusy != true)
        {
            // Start the asynchronous operation.
            BW.RunWorkerAsync();
        }
        txtProgress.Text = "Updating Log File...";
        txtProgress.Refresh();
        myCommand.CommandText = Log;
        myCommand.Connection = SQLConn;
        SQLConn.Open();
        myCommand.ExecuteNonQuery();
        SQLConn.Close();
        if (MessageBox.Show("Database " + DBParam.DatabaseName + " has been successfully created !", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information) == DialogResult.OK)
        {
            txtProgress.Text = "";
        }
    }
    catch (System.Exception ex)
    {
        MessageBox.Show(ex.Message, "Create Database",MessageBoxButtons.OK,MessageBoxIcon.Error);
    }
    finally
    {
        if (SQLConn != null)
            SQLConn.Close();
        if (SQLCreate != null)
            SQLCreate.Close();
        isCreate = false;
        EDFields(!isCreate);
    }
    return;
}
4

2 回答 2

1

看起来您的大部分逻辑都在 UI 线程本身而不是在后台线程中。基本上,您的 UI 正在等待(或休眠),直到创建数据库才能更新。

BW_DoWork 应该调用其他方法。它本质上是您需要在主 UI 线程之外完成的所有工作的包装器。在您的代码中,您将其反转到方法调用工作人员的位置。

于 2012-06-26T02:57:23.113 回答
1

您应该将所有工作包装到创建数据库的单个后台工作人员中。您可以为创建数据库方法的步骤启动一系列方法,并检查每个方法的结果以确定是否应该取消。随着每个步骤(或方法)成功,您可以在回调事件 (BW_ProgressChanged) 上报告进度。在进度更改事件处理程序中,您想在那里更新 txtProgress 控件。如果您开始在后台线程中设置 UI 控件的属性,您将开始遇到跨线程问题。

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Start the BackgroundWorker.
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 1; i <= 100; i++)
        {
        // Wait 100 milliseconds.
        Thread.Sleep(100);
        // 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();
    }
    }
}

BackgroundWorker 对象是使用 WinForms 执行此操作的传统方式,但是您看过Task吗?该任务是特定于 .net 4.0 框架的,因此它可能不适用,具体取决于您所针对的框架版本。

于 2012-06-26T04:02:53.203 回答