0

wpf アプリケーションを作成しました。私のアプリケーションでは、ウィンドウを開き、バックグラウンドでいくつかのファイルをコピーします。コピー中にプログレスバーを表示して更新したいと思います。

私は BackgroundWorker を使用しようとしました:

public partial class FenetreProgressBar : Window
{

    private readonly BackgroundWorker worker = new BackgroundWorker();


    public FenetreProgressBar(ObservableCollection<Evenement.FichierJoint> CollectionFicJointsToAdd)
    {
        InitializeComponent();

        worker.WorkerReportsProgress = true;
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.ProgressChanged +=worker_ProgressChanged;

        worker.RunWorkerAsync(CollectionFicJointsToAdd);

    }

    private void ProgressChanged(double Persentage, ref bool Cancel)
    {
        if (Cancel)
            this.Close();

        worker.ReportProgress((int)Persentage);
    }

    private void Completedelegate()
    {
        this.Close();
    }

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        ObservableCollection<Evenement.FichierJoint> collection = e.Argument as ObservableCollection<Evenement.FichierJoint>;

        //2) On ajoute les fichiers joints à l'évènements ( ce qui va donc les copier dans le répertoire paramétré)

        foreach (Evenement.FichierJoint FichierJoint in collection)
        {
            if (FichierJoint.strPathFichier.Length > 0)
            {
                Evenement.FichierJoint monFichierJoint = new Evenement.FichierJoint(FichierJoint.strPathFichier, App.obj_myEvenement.strEvtNumeroString);

                MaProgressBar.Minimum = 0;
                MaProgressBar.Maximum = 100;

                monFichierJoint.copyObject.OnProgressChanged += ProgressChanged;
                monFichierJoint.copyObject.OnComplete += Completedelegate;

                monFichierJoint.AddFichierJoint();

            }
        }
    }

    private void worker_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
    {
        // Traitement terminé, on ferme la fenetre
        this.Close();
    }

    private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        MaProgressBar.Value = e.ProgressPercentage;
    }

}

プログラムがここに行くとき:

MaProgressBar.Minimum = 0;
MaProgressBar.Maximum = 100;

例外があります:「別のスレッドが所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません」。

Googleとstackoverflowでいくつかの回答を読みましたが、BackgroundWorkerでこのアプローチを使用しようとはしません。

この例外を回避して問題を解決するために、誰か助けてください。

どうもありがとう、

よろしくお願いします :)

4

3 に答える 3

1

あなたcannot modify UI objects from background workerinvokeこのようなUIのメソッドが必要ですdispatcher-

App.Current.Dispatcher.Invoke((Action)delegate
            {
                MaProgressBar.Minimum = 0;
                MaProgressBar.Maximum = 100;
            });

しかし、必要なのは だけなのでset maximum an minimum values、これらの値を backgroundWorker の外に設定することをお勧めしますconstructor-

public FenetreProgressBar(ObservableCollection<Evenement.FichierJoint> 
                      CollectionFicJointsToAdd)
{
    InitializeComponent();

    MaProgressBar.Minimum = 0;
    MaProgressBar.Maximum = 100;

    worker.WorkerReportsProgress = true;
    worker.DoWork += worker_DoWork;
    worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    worker.ProgressChanged +=worker_ProgressChanged;

    worker.RunWorkerAsync(CollectionFicJointsToAdd);

}
于 2013-03-27T16:15:50.083 に答える
0

C# の新しい非同期を使用して、新しい機能やキーワードを待ちませんか? これらは、長時間の操作を行っているときに UI を応答させるように特別に設計されています。

于 2013-03-27T16:12:59.497 に答える
0

これを試してください:

_backgroundWorker.OnProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);

その後

// Event handler
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Update main thread here
}
于 2013-03-27T16:15:46.023 に答える