私はJava環境から来て、ちょうどC#を学び始めました。C#バックグラウンドワーカーUIからの更新
(溶液を見て、質問の最後にスクロールしてください)
私はいくつかの計算を行うと、UIを更新するWebサービスからのいくつかのデータをフェッチするために、バックグラウンドワーカーを使用しようとしているが、私はカント進捗状況を報告するように思われる
私のForm1.ccには、自分のUIフォームを表すMainFormクラス(2つの日付ピッカー、1つのプログレスバー、ボタンが含まれています)があります。私は背景にスタッフを処理するためにすべての私のロジックを持ってAdstage.csで
private void runReport_Click(object sender, EventArgs e)
private void runReport_Click(object sender, EventArgs e)
{
//MessageBox.Show("button pressed\n datefrom "+dateFrom.Value.ToString("yyyy-MM-dd"));
AdStage data=new AdStage(dateFrom.Value.ToString("yyyy-MM-dd"), dateTo.Value.ToString("yyyy-MM-dd"));
//this.progressLabel.Text = "Fetching Data From Adstage";
//data.setUIProgressItems(progressLabel, this.progressBar);
data.setUI(this);
data.startWorker();
}
:私は、次のクリックハンドラをバインドされているボタンを
。
/*constructor*/
public AdStage(String dateFrom, String dateTo)
{
//set the dates
setDates(dateFrom, dateTo);
}
public void startWorker()
{
doBg();//start bg worker...
}
public void setUI(MainForm ui)
{
this.ui = ui;
}
private void setDates(String dateFrom, String dateTo)
{
if (dateFrom.Equals(dateTo))
{
this.dateTo = this.dateTo = dateFrom;
}
else
{
this.dateFrom = dateFrom;
this.dateTo = dateTo;
}
}
private void doRequest(String offset,String url= null,BackgroundWorker worker=null,int p=0)
{
//all of the logic that gets data from the web serivces is here
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine(String.Format("worker_runWorkerCompleted"));
//update ui once the job has finished..
MessageBox.Show("Data Fetched! Total Campaigns: "+this.campaigns.Count());
//this.ui.updateProgress("Fetched " + this.campaigns.Count() + " campaigns",100);
//this.ui.progressLabel.Text = "Fetched "+this.campaigns.Count()+" campaigns";
}
public void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Testing worker_ProgressChanged: "+e.ProgressPercentage.ToString());
MessageBox.Show("Progress: " + this.campaigns.Count());
this.ui.progressLabel.Text = e.ProgressPercentage.ToString();
}
そして、これは私のDoWork関数です
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine(String.Format("worker_doWork"));
//do all major background work here..
BackgroundWorker worker = sender as BackgroundWorker;
worker.ReportProgress(1);
doRequest(offset,null,worker);
(worker as BackgroundWorker).ReportProgress(99, null);
//worker.ReportProgress(100);
}
そうでもID doRequest(の内部報告書の進捗状況を使用している場合)worker_ProgressChangedが呼び出されないようにその機能。作業者は、Webサービスからすべてのページを取得し、終了時にのみレポートを返します。 決してが発生していないworker_ProgressChangedイベント..
EDIT:人々は私がやっているのか理解を助けるために自分のコードを明確に:)
私は労働者がdoBGと呼ばれる方法で作成されています();
private void doBg()
{
Console.WriteLine(String.Format("BG WORKER STARTED"));
this.worker.DoWork += worker_DoWork;
this.worker.RunWorkerCompleted += worker_RunWorkerCompleted;
this.worker.WorkerReportsProgress = true;
worker.RunWorkerAsync();
}
buttn runReportをクリックすると、Adstageクラスのインスタンスが作成されます。 (AdStage data=new AdStage(dateFrom.Value.ToString("yyyy-MM-dd"), dateTo.Value.ToString("yyyy-MM-dd"));
)
そして、そのインスタンス上で、私はへの呼び出しを行うことでMainFormをからバックグラウンドワーカーを開始し、その後
とを(これは私はAdstageクラスからMainFormをメンバーにアクセスできるだけである)UIを設定しますdata.startWorker(); (これは基本的にAdstageクラスのdoBG()関数を呼び出すだけです)。これは、私がdoBG()をAdstageクラスでプライベートに設定したためです。
EDIT 2:doBg()関数の内部this.worker.ProgressChanged += worker_ProgressChanged;
を追加 は、良いヒント:)また
にするために機械学習をのことを指摘するためにあなたにディルクに感謝し、あなたに感謝し、トリックを行うようです誰でも同じ問題がある場合は、代理人を使用してUIを更新することもできます。それを行うにはどのようにアイデアを得るために チェックここでは、この答え:https://stackoverflow.com/a/3303276/514657(それは本当に私が代表者と連携する方法を理解する助けた)
あなたは 'BackgroundWorker' intializeていますが、そのプロパティを設定しているところ、私は表示されない[' WorkerReportsProgress'](https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker。 workerreportsprogress.aspx)を 'true'に変更しますか? – Dirk
私はdoBG()という専用の関数の中でそれを初期化します。 Adstageクラスで – George
そして 'worker_ProgressChanged'メソッドを' worker.ProgressChanged'イベントに追加したことがありますか?私は今、それが動作するはずだと思う ありがとう: – Dirk