3

インターフェイス付きのライブラリがあります。

Public Interface Progress
{
    int ProgressValue{get;set;},
    string ProgressText{get;set;},
}

ライブラリにはCreate(ダミーコード)メソッドがあります。

Public Class TestLibrary
{

    Progress _progress;

    Public void Create()
    {
        foreach(var n in TestList)
        {
            // Do Something
            _progress.ProgressValue = GetIndex(n);
            _progress.ProgressText = "Updating..." + n;
        }
    }
}

このライブラリを参照し、Createメソッドを呼び出すプロジェクトがあります。インターフェイスの進行状況も実装します。

Public Class TestProject : Progress
{
    public int ProgressValue
    {
        get{return progressBar1.Value;}
        set{progressBar1.Value = value;}
    }

    public int ProgressText
    {
        get{return label1.Text;}
        set{label1.Text = value;}
    }
}

これで、アプリケーションを実行すると、プログレスバーが正しく動作し、進行状況が正しく表示されますが、label1のテキストはまったく変更されません。ただし、forループの最後で変更され、ループ内の最後の項目が表示されます。誰かがこれで私を助けることができますか?

注:これらのコードはすべて、現在アプリケーションを持っていないため、テストせずに直接記述されています。構文エラーでごめんなさい。

4

3 に答える 3

8

すべての作業がUIスレッドで行われているようです。そうしないでください。

代わりに、ループ自体をバックグラウンドスレッドで実行し、Control.InvokeまたはControl.BeginInvoke(おそらくProgress実装で)を使用して、UIを更新するためだけにUIスレッドへの呼び出しをマーシャリングします。これにより、UIの処理中に、UIの応答性が向上します(ラベルなどを更新できるようになります)。

于 2012-06-18T09:47:31.940 に答える
5

を使用しましたLabel instead of ProgressBar。このコードを試すことができます[ using BackGroundWorker]-

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

namespace WindowsFormsApplication1
{
    public partial class Form3 : Form
    {
        private BackgroundWorker _worker;
        BusinessClass _biz = new BusinessClass();
        public Form3()
        {
            InitializeComponent();
            InitWorker();
        }

        private void InitWorker()
        {
            if (_worker != null)
            {
                _worker.Dispose();
            }

            _worker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };
            _worker.DoWork += DoWork;
            _worker.RunWorkerCompleted += RunWorkerCompleted;
            _worker.ProgressChanged += ProgressChanged;
            _worker.RunWorkerAsync();
        }


        void DoWork(object sender, DoWorkEventArgs e)
        {
            int highestPercentageReached = 0;
            if (_worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                double i = 0.0d;
                int junk = 0;
                for (i = 0; i <= 199990000; i++)
                {
                    int result = _biz.MyFunction(junk);
                    junk++;

                    // Report progress as a percentage of the total task.
                    var percentComplete = (int)(i / 199990000 * 100);
                    if (percentComplete > highestPercentageReached)
                    {
                        highestPercentageReached = percentComplete;
                        // note I can pass the business class result also and display the same in the LABEL  
                        _worker.ReportProgress(percentComplete, result);
                        _worker.CancelAsync();
                    }
                }

            }
        }

        void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                // Display some message to the user that task has been
                // cancelled
            }
            else if (e.Error != null)
            {
                // Do something with the error
            }
        }

        void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text =  string.Format("Result {0}: Percent {1}",e.UserState, e.ProgressPercentage);
        }
    }

    public class BusinessClass
    {
        public int MyFunction(int input)
        {
            return input+10;
        }
    }
}

数日前に同じ投稿をここに

于 2012-06-18T10:07:58.833 に答える
1

投稿したコードは1つのスレッドを使用しています。つまり、すべての操作は、前の操作が終了した直後に順番に実行されます。GUI要素はすぐに更新できるので、コードはメインスレッド(別名「GUIスレッド」)から実行されると思います。GUIスレッドをブロックすると、GUI(「グラフィカルユーザーインターフェイス」)は、アイドル時間が発生するまで更新されません。

次の例を使用して、反復ごとにラベルを更新し、UIを更新します。

label1.Text = i.ToString();
label1.Refresh();
于 2020-12-12T14:03:23.013 に答える