私はC#とWPFが初めてです。いくつかのコードを見直すために、オンラインドキュメントと例を読むのに何時間もかかりました。コードはSystem.Windows.Controls.Page
をサブクラス化し、バックグラウンド計算を行うにはBackgroundWorker
を使用します。ローカル変数でのみ参照されるBackgroundWorkerオブジェクトを作成するのが適切ですか?
私が学んだことから、この場合にはBackgroundWorker
オブジェクトを作成するための所望の方法、それはクラスのメンバ変数が参照するようにすることです。
例えば、
public class MyPage: System.Windows.Controls.Page
{
// Or: backgroundWorker = new System.ComponentModel.BackgroundWorker()
private System.ComponentModel.BackgroundWorker backgroundWorker;
..
}
しかし、検討中のコードは、ローカル変数が参照するオブジェクトを作成します。
// Inside a class member function
if (someCondition)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(DoWork1);
worker.DoWork += new DoWorkEventHandler(DoWork2);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
worker.RunWorkerAsync(this.DataContext);
}
これは明確ですか? worker
がオブジェクトに明白な唯一の参照であるので、スコープの外にあるオブジェクトはGCの対象となりますか?あるいは、フレームワークは、asnyc関数のコールバックのために余分な参照カウントを追加しますか?
「明確に定義されている」とは、ワーカーオブジェクトがすべてのコールバック(たとえば、RunWorkerCompleted
)が終了するまで、メモリに常駐することが保証されていることを意味します。
ありがとうございます!
それを試してみて、オブジェクトがまだ生きているかどうかを確認します。 – Enigmativity
はい、問題ありません。しかし、あなたが証明を望むならば、上で示唆したように自分自身でテストすること(あるいは 'BackgroundWorker'を継承してファイナライザを追加すること)をGCに何度も強制し、ファイナライザがいつ呼び出されるか見ることができます。 – Evk
これは問題ありませんが、二重のDoWork()はうんざりです。 –