C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


■91539 / )  Re[10]: メモリリークに関して
□投稿者/ 魔界の仮面弁士 (2220回)-(2019/07/04(Thu) 12:11:33)
No91538 (kiku さん) に返信
> AmbientとはフォームのFontを子コントロールが継承する機能であると理解しました。
> よって、フォームのFontと子コントロールのFontは同じインスタンスである場合がある。

アンビエントの具体例として:

.NET Framework の場合、
デザイン画面で Form に Label を貼って、
その後で Form の Font を変更すると、
Label の Font も連動して変更されます。

このとき、デザイナのプロパティ グリッドを見てみると、
Form の Font プロパティは変更されて太字表示されていますが、
Label の Font は細字表示のままとなります。

Label の Font を意図的に変更すれば、Label の Font プロパティも
太字で表示されますが、この状態だと、Form の Font に連動しなくなります。


ところが、.NET Compact Framework の場合、上記の動作が実装されていませんので、
Compact Framework の実装がアンビエントになっている可能性は低いと予想しています。


> この実験の結果をどのように理解していいか
> 正直に言いますと良くわかりませんでした。

.NET Comapct Framework の Font プロパティの getter は、
アクセスするたびに、新しい Font インスタンスを
生成する実装になっている可能性が高いことが伺えます。

その根拠は、
 var f1 = textBox1.Font;
 var f2 = textBox1.Font;
において、f1 と f2 が別のインスタンスとなったという点からです。
(同じインスタンスを返す条件が存在する可能性を否定することは出来ませんが)


また、No91525 のコードで「get_Font」メソッドの実装状況を調べたところ、
Font プロパティは Control クラスで宣言されているのみで、
継承先(Label や Form や ContainerControl 等)でオーバーライドされていないこともわかります。


という事はすなわち、最初の No91509 にて記述されていた、

>> this.lbl_serialnumber.Font.Dispose();//★対策追加

というコードが無価値であるように思うのです。

Font プロパティにアクセスするたびに新しい Font が生成され、
それがすぐに破棄されるだけなのではないかと。
(メモリ負荷等は見ていないので、アンマネージリソースの管理状況までは分かりませんが)


では、そもそも破棄した Font を使おうとしたらどうなるのか?

var f1 = new Font(FontFamily.GenericMonospace, 12, FontStyle.Regular);
var f2 = new Font(FontFamily.GenericMonospace, 12, FontStyle.Regular);
f2.Dispose();
button1.Font = f1;
button2.Font = f2;
button1.Font.Dispose();



てっきり ObjectDisposedException が発生するのかと思いきや、そうでは無いようです。

.NET Compact Framework の場合は、button1 だけが新しいフォントになります。
button2 の方は以前のフォントのままレンダリングされていました。

一方 .NET Framework においては、button1 / button2 両方とも
新しいフォントでレンダリングされました。エラーになることもなく。
返信 編集キー/


管理者用

- Child Tree -