気楽なソフト工房

プログラミングについていろいろな記事を書いています。



mykonos2008

Author:mykonos2008
システムエンジニアとして働いている30代の会社員です。
仕事や趣味でプログラムを書いている方の役に立つ記事を書いていきたいと思っています。
ご意見、ご感想はこちらまで
If you are an english speaker,Please visit my english blog.

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
Visual Studioで開発をしていて、クラスやコントロールを新規追加すると、
たくさんのusing句が挿入された状態でファイルが作成されます。

そして、コーディングを終えてそれらのusing句は使わないで終わってしまうケースも
結構あったりします。

Visual Studioにはこれら未使用のusing句を自動的に削除してくれる便利な機能が備わっていますが、
では、これをうっかりやり忘れたら何が起こるのでしょうか?

プログラムが余計なメモリを使用して遅くなったりするのでしょうか?
ふと気になって調べて見ました。

まず、結論から言いますと、「未使用のusing句」は実行時には何の影響も与えません。

不要なusing句が含まれていようと含まれていなくても、コンパイルの結果、生成されるアセンブリに違いはありません。
コンパイルの結果、生成される中間コードにはusing句に該当する部分は全く生成されないからです。
ですので、不要なusing句があるからと言って、プログラムのパフォーマンスが劣化したりすることはないのです。

では何故、不要なusing句を削除した方が良いのでしょうか?

いくつか理由があります。

まず、1つ目は、当たり前過ぎるのですが、不要なusing句が無いほうがコードが見易いということです。
不要なusing句が無ければそのコードがどのNamespaceを使用しているか一見して分かるようになります。

2つ目は、コーディング時にインテリセンスが提示してくる型の候補が減ることで、
早く目的の型を発見できるようになることです。これも些細な事ですが、
たくさんコーディングする時は結構、大事かもしれません。

3つ目はコンパイルが早くなることです。コンパイラが型解決をするのに不要な名前空間を探しにいくと、
その分、遅くなってしまいます。これについてはよほどソースの数が多くないと影響が無いと思いますが。。

私の主観では1つ目と2つ目は結構大きい理由になるかなと思います。

ただ、最初に言いましたように不要なusing句が有っても実行時には差が出ないので、
消し忘れたからと言って、後から悩む必要は無いと思います。

スポンサーサイト
Silverlightでテキストを右から左にスクロールさせる[HPブログパーツ]を作りました。
フォントの色やサイズ、スクロール速度など細やかな設定が可能になっています。

フリーですので、是非お使いください。


テキストスクロールのダウンロード

■ページへの埋め込み方法
HTMLに以下のObjectタグを貼り付けます。
<div id="Div2">
   <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="350" height="40">
   <param name="source" value="Billboard.xap"/>
   <param name="background" value="white" />
   <param name="minRuntimeVersion" value="3.0.40818.0" />
   <param name="autoUpgrade" value="true" />
   <param name="initParams" value="conf=board.xml"/>
   <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
      <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Microsoft Silverlight を入手" style="border-style:none"/>
   </a>
   </object>
   <iframe style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>
</div>

Objectタグのwidthやheightを指定して、Silverlightの領域のサイズを指定してください。

<param name="source" value="Billboard.xap"/>はSilverlightの実行ファイルであるxapファイルへのパスを示しています。
HTMLファイルと同じディレクトリに配置する場合は、上記のようにファイル名だけで記述します。ディレクトリが異なる場合は、
[xapdir/Billboard.xap]のようにHTMLファイルからの相対パスを指定します。

<param name="initParams" value="conf=board.xml"/>はこのパーツの設定を記述したファイルへの相対パスを指定します。
相対パスはxapファイルからのパスを記述します。この記述を省略した場合、xapファイルと同じディレクトリに「board.xml」が
ある前提で設定を読み込みます。

■設定方法
Objectタグの<param name="initParams" value="conf=board.xml"/>要素に記述したファイルに
以下の内容を記述します。(ダウンロードファイルにはサンプルが含まれています。)
このファイルはUTF-8で保存してください。

<?xml version="1.0" encoding="utf-8" ?>
<board-settings>

  <!-- 
     文字の色(省略した場合、黒が設定されます。)
  -->
  <color>black</color>
  
  <!-- 
     背景色(省略した場合、白が設定されます。)
  -->
  <background>white</background>

  <!-- 
     文字の大きさ(省略した場合、12が設定されます。)
  -->
  <font-size>12</font-size>

  <!-- 
     次のテキストに切り替わるまで停止している時間(秒) (省略した場合、3が設定されます。)
  -->
  <interval>2</interval>

  <!-- 
     テキストが右から左にスクロールするのにかける時間(秒)
     (省略した場合、スクロール幅に合わせて自動計算した値を設定します。)
  -->
  <scroll-time>9</scroll-time>
  
  <!-- 
     枠線の色(省略した場合、黒が設定されます。)
  -->
  <border-color>green</border-color>
  
  <!-- 
     枠線のサイズ 枠線を付けない場合は0に設定してください。
     (省略した場合、0が設定されます。)
  -->
  <border-size>1</border-size>
 
  <!--
     表示するテキストのリスト
     表示するテキスト毎にtextタグを定義します。
  -->
  <text-list>
    <text>
      <!-- 表示するテキストの内容(省略不可) -->
      <title>これはテキストをスクロールさせるブログパーツです。</title>
      
      <!-- テキストのURL (省略した場合、テキストがリンクになりません。) -->
      <url>http://csfun.blog49.fc2.com/</url>
      
      <!-- 
         テキスト個別の色 board-settings/colorよりも優先されます。
         (省略した場合、board-settings/colorの値が設定されます。)
      -->
      <color>blue</color>      
    </text>
    <text>
      <title>気楽なC#工房はC#やSilverlightについて書くブログです。</title>
      <url>http://csfun.blog49.fc2.com/</url>
    </text>
  </text-list>
</board-settings>


色を指定する場所では以下のURLの「定義済みの色」に記載されている141色の中から指定可能です。
色見本

■簡単な配置方法
Objectタグの要素の指定の仕方によっては、xapファイルとhtmlファイル、board.xmlファイルを同じディレクトリに
配置する必要はないのですが、簡単な方法はすべて同じディレクトリに置いておくことです。

不具合などありましたらご遠慮なくご報告ください。

4月16日、ついに「Silverlight 4」の正式版がリリースされました。
早速、インストールしてデモを試してみたりしました。

そして、喜んでいたところ、戻って、今まで使用していた開発環境の
「Visual Web Developer 2008 Express Edition」+ 「Silverlight 3 ソフトウェア開発キット」で
デバッグしようとしたところ、突然、「Silverlight マネージ デバッグ パッケージがインストールされていません」
というエラーが発生するようになりました。

思い当たる原因は「Silverlight 4」をインストールしたことしかありません。

いろいろ調べたところ、以下のURLで公開されている「Silverlight 4 開発者向けランタイム」を
インストールすることで解決しました。


http://msdn.microsoft.com/ja-jp/silverlight/bb187452.aspx


ふうーっ、何故だかよく分かりませんが、とりあえず良かったです。
電光掲示板のように文字列を左から右にスクロールさせるサンプルを作ってみました。


Silverlightではアニメーションを簡単に実現できる仕組みが提供されているので、とても楽に出来ました。

まず、XAML側に、Canvasを定義し、その中にスクロールさせる文字列をTextBlockで配置します。
そしてResourceとしてStoryBoardを定義します。そして「DoubleAnimation」を使って、TextBlockの「Canvas.Left」プロパティを
変化させます。

DoubleAnimationのFromやToは、HTMLに指定されるSilverlightのサイズに、動的に合わせて変化するようにしたかったので
コード上で指定するようにしました。

以下がXAMLの内容です。

<UserControl x:Class="BulletinBoard.BoardControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Loaded="UserControl_Loaded">
    <UserControl.Resources>
        <Storyboard x:Name="_storyBoard">
            <DoubleAnimation x:Name="_animation" RepeatBehavior="Forever" Storyboard.TargetName="_boardText"
               Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:10"/>
        </Storyboard>
    </UserControl.Resources>
    <Canvas x:Name="LayoutRoot" Background="Gray">
        <TextBlock Foreground="White" FontSize="15" x:Name="_boardText">
          Silverlightで文字列を横にスクロールさせるサンプルです。
        </TextBlock>
    </Canvas>
</UserControl>

次にコードの方からDoubleAnimationのFromをSilverlight領域の幅の値に、
Toを0からTextBlockの幅をマイナスした値に設定しました。

ActualWidthとActualHeightを取得する必要があったので、
DispactherのBeginInvokeを使用して、レイアウトシステムの処理の後に取得処理が
走るようにしました。

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        Dispatcher.BeginInvoke(() =>
        {
            //文字の縦表示位置を設定する
            Canvas.SetTop(_boardText, (this.ActualHeight - _boardText.ActualHeight) / 2);

            //文字がすべて隠れるToの位置を設定する
            _animation.To = - _boardText.ActualWidth;

            //アニメーションのFromをコントロールの幅に設定する
            _animation.From = this.ActualWidth;

            //アニメーションを開始する
            _storyBoard.Begin();
        });
    }

文字列や各種設定を外部から与えられるようにもう少し作りこんでみようと思います。

さて、いよいよ、「Silverlight4」のリリースが近づいてきましたね、楽しみです。
そこで、本日は「Silverlight4」のComオートメーションのちょっとしたTipsをご紹介させていただきます。

Comオートメーションをアプリから利用する際(Silverlightに限らず)、一番頭を悩ませるのは
一度取得したComオブジェクトのリソース解放です。使用したComオブジェクトを1つでも、
解放し忘れると、Comオブジェクトのプロセスが残ってしまいます。

「Silverlight4」ではComオブジェクトは、「IDisposable」インターフェースを実装しているので、
「using句」を利用したり、直接Dispose()をコールすることで、リソースを解放することが出来ます。

ただ、問題はほとんどの場合、解放しなければいけないオブジェクトが1つで済まないことです。
例えばExcelをComオートメーションで利用して、新規のブックに、データを書き込んで保存処理を
行うとします。
この場合、以下のようなオブジェクトが必要になります。

・Application(Excel)
・Workbooks
・Workbook
・Worksheets
・Worhsheet
・Range
・Font
・Interior

Rangeなんかは入れ子になったりするので、実際はもっと多いです。
これらを「using」句を使って解放するとなると、、、

   using(dynamic excel = AutomationFactory.CreateObject("Excel.Application")){
      using(dynamic workbooks = excel.WorkBooks){
         using(dynamic workbookObject = workbooks.Add()){
            /////////どんどん入れ子に。。。
         }
      }
   }

ちょっときつい。。ですね。。

そこでちょっとしたライブラリを考えてみました。
アプリケーションで、利用するComオブジェクトをラップするクラスを作り、
IDisposableインターフェースを実装します。

例えばWorkbooksのラッパーはこんな感じです。
    public class Workbooks : IDisposable
    {
        //Comオブジェクト
        private dynamic _workbooks;

        internal Workbooks(dynamic workbooks)
        {
            _workbooks = workbooks;
        }

///省略
    }

そして、新規ブック追加など新たなComオブジェクトへの参照が生成される処理で、
以下のようにして、新規生成されたオブジェクトを管理コレクションに登録しておきます。

        public Workbook CreateNewBook()
        {
            dynamic workbookObject = _workbooks.Add();

            //ブックのラッパー
            Workbook workbook = new Workbook(workbookObject);

            //管理コレクションに登録する処理
            AddChildren(workbook);

            return workbook;
        }

そして、Dispose()メソッドの中で、ラップしているComオブジェクトと、管理コレクションに登録されている
派生オブジェクトを解放する処理を記述します。

        public void Dispose()
        {
            try
            {
                //子オブジェクトを解放する
                ReleaseChildren();

                ((IDisposable)_workbooks).Dispose();

            }
            catch { }
        }

こうすることで何がよいかと言うと利用する側は以下のようなコードで済みます。

    using(Workbooks books = excel.Workbooks){
        //いろんな処理
    }

外側のWorkbooksがそれから派生する他のComオブジェクトを管理し、またそれらのラッパークラスが
さらにその子供を管理し、それぞれリソース解放を担ってくれるので、利用する側は、自分が解放したい単位で、
外側のオブジェクト(今回はWorkbooks)を決定し、それのみ解放処理を記述すればよいのです。

実際は、「SilverOffice」という名前のもう少し手の込んだサンプルライブラリを作成してみました。
ただ、オブジェクトやプロパティは全然そろえていないので、考え方が使えそうであれば、
必要なオブジェクトやプロパティを追加して使用してみてください。

SilverOfficeのダウンロード

いよいよ、「Silverlight 4」のリリースが近づいてきました。私も待ちきれず、VisualStudioのRC版でいろいろ試してみています。
「Silverlight 4」の新機能の中でも、私が最も注目しているのはComオートメーションの機能です。

ExcelとComオートメーション機能を使って、いろいろ試してみているのですが、なかなか快適です。
Silverlightでは遅延バインディングしか対応していないのですが、C# 4.0から導入された「dynamic」キーワードを
使用できるのでかなり楽にきれいなコードを書くことが出来ます。

例えば、Excelを起動してブックを開くコードは以下のようにして記述することが出来ます。

//Excelオブジェクトを生成する
dynamic excelObject = AutomationFactory.CreateObject("Excel.Application");

//Excelを可視化する
excelObject.Visible = true;
excelObject.UserControl = true;

//ブックを開く
dynamic workbooks = excelObject.WorkBooks;
dynamic workbookObject = workbooks.Open("ファイルパス");

以前のC#だとリフレクションの機能を利用して面倒くさいコードを書かないといけなかったので、
かなり楽になりました。

※ComオブジェクトはIDisposableインターフェースを実装しているので使用したオブジェクトは
すべて、Dispose()することをお忘れなく。

ところで、Excel2003とXP、またはVistaの組み合わせだと、Workbookの「Save」、または
「SaveAs」を使用すると、オブジェクトを破棄した後もExcelのプロセスが残ってしまうと
いう衝撃的な問題があるようです。解決策をご存知の方は是非教えてください。

今のところ、WMIをComオートメーションを介して使用して、プロセスをKILLするくらいしか
解決策が思いつきません。。。。


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