スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
拍手コメントを見る

AnimatedGIF をコントロールに貼り付けて放っておくとCPUを食いつぶす件

いやぁ、久々にブログ書きます。twitterばかりでしたから。
たまには長文って思っていたりしたんですが、根が面倒くさがりなので。

さて、本題です。

先日、AnimatedGIFが張り付いたコントロールを表示して放置しておいたら、CPU使用率が徐々に上がっていく現象が起こりました。
以前はそんなこと無かったよな?と思いつつ、起きるときと起きないときの違いがわかりました。

起きない方は .NET1.1 で作られて、
起きる方は .NET2.0 で作られている

という事がわかりました。
.NET 3.0 ならどうなん?ということで試してみたのですが、やっぱりCPUが食いつぶされていきます。

さぁて、困りました。どうしましょ?
.NET2.0以降を利用する上では、このままでは連続稼働させることができなくなってしまいます。

回避方法はないものかいなと思案していたところ、ある方から ImageAnimator クラスは使えないだろうか?というヒントを頂きました。
へぇ、ほぉ。

というわけで、利用方法を調べつつ実装してみました。
001:// アニメーションGIFの確認
002:private Bitmap mMyImage = new Bitmap(GetType(), "MyAnimatedGIF.GIF");
003:private bool mIsAnimated = false;
004:
005://
006:// イメージ貼り付け先コントロール(lblX)のPaintイベントハンドラを実装
007://
008:private void lblX_Paint(object sender, PaintEventArgs e)
009:{
010: if (ImageAnimator.CanAnimate(mMyImage))
011: {
012: // アニメーション可能なイメージなら、フレームを1つ進める
013: ImangeAnimator.UpdateFrames();
014: }
015: e.Graphics.DrawImage(this.mMyImage, new Point(0,0));
016:}
017:
018://
019:// アニメーション処理をスタートしたいとき呼んでね
020://
021:public void StartAnimation()
022:{
023: if (this.mIsAnimated) return;
024:
025: if (ImageAnimator.CanAnimate(mMyImage))
026: {
027: // アニメーション可能なイメージなら、開始依頼
028: // onImageFrameChanged イベントハンドラオブジェクトに処理依頼
029: ImangeAnimator.Animate(this.mMyImage, new EventHandler(onImageFrameChanged));
030: this.mIsAnimated = true;
031: }
032:}
033:
034://
035:// アニメーション処理をストップしたいときに呼んでね
036://
037:public void StopAnimation()
038:{
039: if (ImageAnimator.CanAnimate(mMyImage))
040: {
041: // アニメーション可能なイメージなら、終了依頼
042: // onImageFrameChanged イベントハンドラオブジェクトに処理依頼
043: ImangeAnimator.StopAnimate(this.mMyImage, new EventHandler(onImageFrameChanged));
044: }
045: this.mIsAnimated = false;
046:}
047:
048://
049:// アニメーションに関する処理を行うイベントハンドラ
050://
051:private void onImageFrameChanged(object sender, EventArgs e)
052:{
053: // イメージ貼り付け先のコントロール(lblX)の再描画依頼(lblX_Paint呼び出し)
054: this.lblX.Invalidate();
055:}

適当なユーザーコントロール(またはフォーム)に、lblX という名前のLabelコントロールがあることを想定しています。また、歴史的背景からAnimatedGIFの貼り付け先は、PictureBoxではなくLabelを使っています。

で、結果ですが、CPUのバカ食いは解消されました。
.NET1.1 を利用する上では、上のコードは一切不要ですが、.NET2.0以降は考慮が必要となってきます。

ちなみに、
029:        ImangeAnimator.Animate(this.mMyImage, new EventHandler(onImageFrameChanged));
:
043: ImangeAnimator.StopAnimate(this.mMyImage, new EventHandler(onImageFrameChanged));

は、
029:        ImangeAnimator.Animate(this.mMyImage, onImageFrameChanged);
:
043: ImangeAnimator.StopAnimate(this.mMyImage, onImageFrameChanged);

でもコンパイルは可能ですが、CPU使用率はぐんぐん上がっていきます。
イベントハンドラオブジェクトに処理させる必要があるため、new EventHandler(...)とやっているんですね。

・・・いまいち理解できてませんけど。 拍手コメントを見る

テーマ : プログラミング
ジャンル : コンピュータ

コメント

非公開コメント
ブログ内検索
プロフィール

雷ぶ

Author:雷ぶ

最近の記事
最近のコメント
最近のトラックバック
カテゴリー
月間アーカイブ
ブロとも申請フォーム

この人とブロともになる

RSSフィード
リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。