|
■No91530 (魔界の仮面弁士) に追記 >>あと、経験則的なところで言えば、.NET Compact Framework 環境の場合、 >>オブジェクトの使用後は、参照変数に Nothing 代入を積極的に行った方が良いみたいです。 > Nothing の代入有無で、本当に解放状況が変化するかどうかを確認してみました。
すみません! C# の質問に、うっかり VB で回答してたことに、今朝になって気がつきました。
# .NET 対応前、CE アプリを eVB3 で行ってきた期間が長すぎて、 # CE 環境だと反射的に VB で書く癖が…。orz
> 端末を再起動して、空きメモリが十分に確保されている状態において、 > Button1 でモードレス フォームを表示させた後、 > Button2 でそれを Close させています。 > すると、Close 直後の ★の行の Nothing 代入がコメントアウトされていた場合、 > Form2 および LabelEx が直ちに Dispose されないケースが確認できました。
上記の「Close 後、直ちに Dispose されていない」現象ですが、 改めて C# (CFx 3.5 SP1) でも実験してみたところ、上記の状況を再現させられませんでした。 Close されたら、null を代入せずとも即座に Dispose されているようにみえる…。
改めて、昨日の VB コードでも再検証してみましたが、 昨日と比べて問題の再現率が大幅に低下していました。 狙って再現させることは難しそうです。
public partial class Form1 : Form { private Form2 f = null; public Form1() { InitializeComponent(); DoubleClick += delegate { Close(); }; }
/// <summary>新規に Form2 を表示するコード</summary> private void button1_Click(object sender, EventArgs e) { f = new Form2(); f.Show(); }
/// <summary>直前に表示された Form2 を閉じるコード</summary> private void button2_Click(object sender, EventArgs e) { if (f != null /* && !f.IsDisposed */) { f.Close(); // f = null; // ★ } } }
// -=-=-=-=-=-=-=-=-=-=-=-=-
public partial class Form2 : Form { private readonly Guid Id = Guid.Empty; public Form2() { Id = Guid.NewGuid(); Trace.WriteLine(String.Format("==> {0} 生成 {1}", GetType().Name, Id)); InitializeComponent(); Controls.Add(new LabelEx()); Text = Id.ToString(); DoubleClick += delegate { Close(); }; // Disposed += delegate { Trace.WriteLine(string.Format("<== {0} 破棄 {1}", GetType().Name, Id)); }; } public sealed class LabelEx : Label { private readonly Guid Id; public LabelEx() { Id = Guid.NewGuid(); Trace.WriteLine(String.Format("==> {0} 生成 {1}", GetType().Name, Id)); Text = Id.ToString(); //Disposed += delegate { Trace.WriteLine(string.Format("<== {0} 破棄 {1}", GetType().Name, Id)); }; } protected override void Dispose(bool disposing) { Trace.WriteLine(string.Format("<== {0} 破棄 {1} ({2})", GetType().Name, Id, disposing)); base.Dispose(disposing); } } protected override void Dispose(bool disposing) { Trace.WriteLine(string.Format("<== {0} 破棄 {1} ({2})", GetType().Name, Id, disposing)); if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } }
|