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);

        }

\Do Work イベント

 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;
    }

\メイン UI を更新

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

\私の主な UI 操作

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

データベースを作成する単一のバックグラウンド ワーカーにすべての作業をラップする必要があります。create database メソッドのステップの一連のメソッドを開始し、各メソッドの結果をチェックして、キャンセルする必要があるかどうかを判断できます。各ステップ (またはメソッド) が成功すると、コールバック イベント (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 に答える
1

ほとんどのロジックは、バックグラウンド スレッドではなく UI スレッド自体にあるようです。基本的に、UI はデータベースが更新される前に作成されるまで待機 (またはスリープ) します。

BW_DoWork は他のメソッドを呼び出す必要があります。これは基本的に、メイン UI スレッドから離れて実行する必要があるすべての作業のラッパーです。コードでは、メソッドがワーカーを呼び出している場所を逆にしています。

于 2012-06-26T02:57:23.113 に答える