2010年12月7日火曜日

[Android]コンテンツのアイデア

私はバイクに乗ります。そしてひどく方向音痴な上に貧乏です。
一方Android系スマートフォンには、ほとんどGPSが搭載されています。そして画面が大きい。
ということで、以下のようなコンテンツを開発しようかと考えています。

  • 事前に大雑把な地図をダウンロードしておく
  • 現在どこいらへんにいるかをポイントして表示する
  • 家がどっちの方向にあるかを表示する

です。以前、一人でぶらりと大阪方面に出かけたことがあったんですが、いざ帰ろう。と思ったときに家がどっちのほうにあるのかさっぱりわからなくなってしまって。。。
ライセンスの問題があるかも知れませんが、地図はとりあえずGoogleさんから失敬して、緯度経度のマトリックスから、それらしい画像を選び、その上に現在地および家のある方向を指す。的なアプリケーションっでどうかなぁと。

地図の精度は、大きな国道および、高速道路・有料道路が若干わかる位のレベルでいこうかと思っています。イメージ的には、高速道路でもらえるレベルの地図の範囲でしょうか。

・・・と思っていたんですが、検索してみると同様のソフトがすでにあるんですね。MapDroydとか。。。

2010年11月9日火曜日

[Android]SDKのインストール

AndoroidのSDKをダウンロードし、Installed PackegesでUpdate All..を実施しました。
コレやらないと新しいバージョンの開発環境がそろわないので。
で、やってみると、↓のようなメッセージが。。。

「HTTPS SSL error. You might want to force download through HTTP in the settings.」

は?、会社ではこんなメッセージ出なかったのに。。。
で調べてみると、[Setting]→「Force https://... sources・・・」のチェックをオンに。
するとダウンロードが始まりました。

OSの違いか通信環境の違いなのか。。。ブラウザで見るとXML自体は表示できるのに。何なんだろう?

2010年10月26日火曜日

[Android]ちょっとホサレタ感じかも

えー、持ち前のガッツを変われて、短納期のキツイ系プロジェクト配置転換されました。
そのプロジェクトは今、ちょっと話題のAndroid系スマートフォン携帯コンテンツの開発です。
窓際でおとなしくしていたつもりなんですが、Javaなら昔とったキネズカ的なことをえらい人から言われた感がありました。なんとなくですが、断ったらアレ(黒)かなって感じがしました。

というわけで、当座、MS系技術からJava系の技術に変わります。ということでAndroid系の話題も少々織り交ぜていきます。
で、配属から1週間くらいたちましたが、やってみると結構面白い。なんと言えばいいか、懐かしさと新しさをかねそろえたような感じです。んーいってみればJava AppletとXML系技術の融合といいますか。。。

で早速基本ですが、Activityというクラスがあります。このクラスはJApplet相当のクラスで、画面の制御など一式を操作するプログラムのエントリーポイントです。
ViewがXMLで定義できるところとイベントの分離ぷりが、すっきりしたデザインになっている感じですね。

2010年10月1日金曜日

[.NET]いまさら?Parallel.Forを使ってみた(その2)

先日実験していました、マルチスレッドの件で、いかにして高速化するかを検討してみたんですが、同期化するオブジェクトを分けるというアイデアを思いつきついたので、実行してみました。
で実験の結果、5回計測で14.420秒となり、約13%の性能向上しました。しかしメモリは画像サイズ分増加します(がいまどきのH/Wであれば知れていますね)。

プログラム言語であるC#にも簡単にマルチスレッドを扱うような機構が用意されており、便利になった反面、マルチスレッドに関する知識もある程度必要と実感しました。
これからのCPUはMoreからManyになる。そういわれています。もっと勉強していかないとね。

で、コードはこんな感じ。

private void btnGlay2_Click(object sender, EventArgs e)
{
    textBox1.Text = "グレースケール化(2)";

    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
    sw.Start();

    Bitmap bmp = new Bitmap(ctlPicture.Image);
    int h = bmp.Height;
    int w = bmp.Width;
    Parallel.For(0, w, delegate(int i)
    {
        for (int j = 0; j < h; j++)
        {
            Color color;
            lock (bmp)
            {
                color = bmp.GetPixel(i, j);
                // 計算式にて、値を算出してセットする
                //int col = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);
                //int col = (int)((color.R + color.G + color.B) / 3);
                int col = (int)Math.Round((color.R + color.G + color.B) / 3.0d);
                Color pix = Color.FromArgb(col, col, col);
                bmp.SetPixel(i, j, pix);
            }
        }
    });
    ctlPicture.Image = bmp;

    sw.Stop();
    textBox1.Text = String.Format(textBox1.Text + " 完了{0:#,##0}ms", sw.ElapsedMilliseconds);
}

2010年9月25日土曜日

[.NET]いまさら?Parallel.Forを使ってみた(その1)

簡単に平行処理ができる、Parallel.Forというクラスが.NET4で提供されています。で、以前作成した、GDD Blog: [.NET]画像処理グレースケール化(1)の処理をParallel.Forにしたら速くなるか?とおもってちょっと実験。小さい画像だと差が出ずらいので、ちょっと大きめの画像(3,008×2,000)で上記リンクの処理を5回動作させてみると、平均で16.32秒でした。タスクマネージャでCPUの稼動を見ているとほぼ50%で停滞。というか1コアしか使っていない。

で、以下のコードで実行してみると、CPU稼動率は100%で張り付いたものの、5回の平均を計ると18.297秒。なんと10%くらい性能が悪化していました。BitmapのGetPixおよびSetPixはマルチスレッドに対応していないようで、結果的に同期のコストがかかることが原因ということがわかりました。

で、残念なコードは以下のとおり。
private void btnGlay2_Click(object sender, EventArgs e)
{
    textBox1.Text = "グレースケール化(2)";

    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
    sw.Start();

    Bitmap bmp = new Bitmap(ctlPicture.Image);
    int h = bmp.Height;
    int w = bmp.Width;
    Parallel.For(0, w, delegate(int i)
    {
        for (int j = 0; j < h; j++)
        {
            Color color;
            lock (bmp)
            {
                color = bmp.GetPixel(i, j);
                // 計算式にて、値を算出してセットする
                //int col = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);
                //int col = (int)((color.R + color.G + color.B) / 3);
                int col = (int)Math.Round((color.R + color.G + color.B) / 3.0d);
                Color pix = Color.FromArgb(col, col, col);
                bmp.SetPixel(i, j, pix);
            }
        }
    });
    ctlPicture.Image = bmp;

    sw.Stop();
    textBox1.Text = String.Format(textBox1.Text + " 完了{0:#,##0}ms", sw.ElapsedMilliseconds);
}

2010年9月17日金曜日

[他]VBSで指定時間待つダイアログ

うちの会社の勤怠システムは、URLのGETで打刻を実施しています。
毎日ブラウザでGETするのでもいいですが、面倒なので、VBSでGETするやつを組んでみました。
土曜日とかは打刻したくないときもあるので、確認のダイアログを出して打刻するかどうかを確認する仕様です。

が、コレを押すのを忘れちゃうことが時々あって。。。ということで、一定時間経過したら自動的にダイアログを自動的に閉じて処理を継続する方法を見つけたので紹介します。朝、おなかが痛くても、ログインさえすれば、打刻OK的な。。。でコードはこんな感じ。

Dim objShell: Set objShell = WScript.CreateObject("WScript.Shell")
'第2引数:待ち時間
'第4引数:出力アイコン+ボタンパターン
Dim intRes: intRes = objShell.Popup("やっちゃいますか?",3 ,"どうする?",32+1)

Select Case intRes
   case vbOk     MsgBox("OK!!")
   case vbCancel MsgBox("Cancel!!")
   case -1       MsgBox("Time Out!!")
End Select

2010年9月15日水曜日

[他]VBSでHTTP通信&文字のエンコード

えぇ、まぁうちの会社の打刻システムはHTTPでGETすることにより打刻します。

先日システムのバージョンアップがあり、知らぬ間にShiftJISからMS932にエンコードへ変えられていました。
MSXML2.ServerXmlHttpではMS932には対応していないため、取得した文字列が正しくデコードされず、日本語が化けてしまいます。で、標準的なもので何とかならないものか。と調査してみると、ADODB.Streamで解決できることがわかりました。ということでこんな感じ(一部手打ちなので、エラーが出たらスマソ)。

Dim objHttp: Set objHttp = WScript.CreateObject("MSXML2.ServerXmlHttp")
Dim strXML

Call objHttp.Open("GET""https://hogehoge.com/kintai/dakoku.do?id="&strID, False)
If objHttp.status = 200 Then
    Dim objADO:    Set objADO = WScript.CreateObject("ADODB.Stream")

    objADO.Open
    objADO.Type = 1'adTypeBinary
    objADO.Write objHttp.responseBody

    objADO.Position = 0
    objADO.Type = 2'adTypeText
    objADO.Charset = "Shift_JIS"
    strXML = objADO.ReadText()
Else
    MsgBox("HTTP ERROR !! CODE=" & objHttp.status)
End If

2010年9月9日木曜日

[.NET]byte.Equals(int)

先日、バイト列の中を検索し、特定のコードが出てくる位置を特定するという処理を組んでいました(共有ファイルのやつね)。コード的には、Array.IndexOfをつかって0x00を探しているのですが、なぜか結果が-1(みつからない)で、もしかして型の違いというのを思い出して、実験してみました。

int.Equals(byte)はtrueなのに、byte.Equals(int)はfalseなんですね。バイト列の検索には要注意ですね。でコードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    var buf = new byte[16] { 0123456789101112131415 };

    var idx = 0;
    //がっかりなコード
    //for (idx = 0; idx < buf.Length; idx++)
    //{
    //    if (buf[idx] == 9)
    //    {
    //        break;
    //    }
    //}

    //残念なコード(-1がかえる)
    //idx = Array.IndexOf(buf, 9);

    //普通のコード
    idx = Array.IndexOf(buf, (byte)9);

    System.Diagnostics.Debug.WriteLine("発見位置=" + idx);

    int int1 = 1;
    byte byte1 = 1;

    System.Diagnostics.Debug.WriteLine("int1==byte1? ->" + (int1 == byte1));
    //int1==byte1? ->Trueと表示される
    System.Diagnostics.Debug.WriteLine("byte1.Equals(int1)? ->" + byte1.Equals(int1));
    //byte1.Equals(int1)? ->False
}

2010年8月31日火曜日

[.NET]ドッキングウィンドウ

テスト用のドライバを作成していたのですが、プロパティーグリッドを表示しっぱなしにしておくと、画面が狭くなってしまうので、ドッキングウィンドウにできないかと思って調査してみました。

調査すると1つめにヒットするのは「.NETでDocking Windowを使う」ですが、そこに乗っていない「DigitalRune Docking Windows for .NET」というライブラリを使ってみました。

使い方は簡単でした(コード割愛)ドッキングされる側のウィンドウはFORMなんですが、基本クラスを手動で変更する必要がありました。
その他は、サンプルがついているので、必要な部分をカットアンドペーストでいけると思います。

このライブラリは商用で使うには有償になりますが、フリーウェアではフリー?になるようです。
ライセンス関係の規約がPDFで提供されています。私の低レベルな英語力ではフリーになると読み取れました。。。ご利用の際はご確認ください。

その他、エディタのライブラリなどあるようです。今度調べてみよう。

2010年8月23日月曜日

[.NET]QRコード関係のライブラリ

QRコード関係のライブラリを探していたのですが、フリーで使えてかつ、エンコードとデコードの両方をサポートしているものがありました。

QRコードをアプリケーションで作成するには?[C#、VB]

備忘録用にメモ。

2010年8月19日木曜日

[.NET]メモリマップファイル

C#4.0から使えるようになったメモリマップファイルですが、興味本位でちょっと触ってみました。
コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.IO.MemoryMappedFiles;

    MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("TestMMF"1024);
    using (MemoryMappedViewAccessor mmfa = mmf.CreateViewAccessor())
    {
        var data = "1192つくろう鎌倉幕府! " + DateTime.Now.ToString();
        var byteData = Encoding.UTF8.GetBytes(data);
        mmfa.WriteArray(0, byteData, 0, byteData.Length);
        mmfa.Flush();
    }
}

private void button2_Click(object sender, EventArgs e)
{
    MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("TestMMF"1024);
    using (MemoryMappedViewAccessor mmfa = mmf.CreateViewAccessor())
    {
        var buf = new byte[1024];
        mmfa.ReadArray(0, buf, 0, buf.Length);

        int len = 0;
        for (len = 0; len < buf.Length; len++)
        {
            if (buf[len] == 0x00)
            {
                break;
            }
        }

        var str = Encoding.UTF8.GetString(buf, 0, len);

        MessageBox.Show("結果=[" + str + "]");
    }
}


結果、プロセス間で情報を共有できました。
しかし、System.IOとの連携というか、私が見つけられなかっただけなのかもしれませんが、Stream系のクラスとうまく連携できないようです。
そのあたり今度調査してみよう。

2010年8月15日日曜日

[他]Do-It-Yourself シリーズ

先日、某BBSを見ていると、Do-It-Yourself シリーズなるページが紹介されていました。
ASP.NET/xamlの2種類があるようです。

順を追って学習できそうなので、よさそうな感じです。

2010年8月12日木曜日

[.NET]大文字小文字を区別しないで一括置換する

テストのドライバで、結果で指定されているURLプロトコルをHTTPSからHTTPに一括置換していました。
まぁローカルのIISでHTTPSを使えるようにするのが面倒だったのが理由なんですが。

で、とりあえず、string.Replaceで簡単に実装していました、時々httpsとなっているものがあり、置換されず通過してくるケースがありました。
で、置換する必要のある文字のパターンも増える可能性があり、大文字・小文字の区別なく一括置換できないものかと調べてみると、正規表現でいけることがわかりました。コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.Text.RegularExpressions;
    var str = "abc/ABC/aBcC/aAaB/aABCc";
    System.Diagnostics.Debug.Write(Regex.Replace(str, "abc""123", RegexOptions.IgnoreCase));

    // 出力は↓こんな感じ
    // 123/123/123C/aAaB/a123c
}

いやー意外と簡単。

2010年8月10日火曜日

[他]VS2010Expressでは、.NET Frameworkへのステップインが可能?

先日何気なく、C#2010の設定画面を見ていると、デバッグの設定で「シンボル」というのがあることに気づきました。これって、2008のときにexpressより上位のエディションに搭載された.NET Frameworkにステップインする機能では?

ということで、早速設定してみました。でデバッグしてみたんですが、ステップインしませんでした(textBox1.Refresh())。キャッシュのフォルダも空。何か条件があるのだろうか?

2010年8月2日月曜日

[SQL]大文字・小文字が異なる場合のみを抽出する(SQLServer)

SQLServerでは大文字と小文字を区別しません。Oracleはどうなんだろう?
で、先日、大文字で登録されたデータと小文字で登録されたデータの混在があり、困っている。と相談されました。
SQL上では'A'='a'がなりたちますが、プログラム側では'A'≠'a'なので、その辺で困っている模様でした。

とりあえず、
update T_TEST2 SET text1=upper(text1)


でできるんじゃない?と教えてあげたのですが、対象のレコードと個数が知りたい。とのことでした。
ということで、これで、いかが?と提示したところ、喜んでかえって行きました。

--だめな例
--select * from T_TEST2 where text1<>upper(text1)
--OKな例
select * from T_TEST2 where convert(varbinary,text1)<>convert(varbinary,upper(text1))


convertのvarbinaryは、指定の値を16進数で表現します。ソレをUPPERと組み合わせて差が出たものが対象。という事になります。
他のDBでも同じようなストアド・関数があれば実現できると思います。

2010年8月1日日曜日

[Excel]セル内の箇条書きの個数を判別する

Excelで表を作成したときに、1のセル内に、とある条件を箇条書きにしたものと、箇条書きの個数を1行に表現したいということがありました。
もちろん手入力すればいいのですが、後で修正するのが面倒だし、間違える恐れがあるので、コレの自動化を考えてみました。
もちろんマクロを使えば計算できることはわかっていたのですが、マクロを使わずにできないか。と考えて実施してみました。答えは単純で、特定の文字を除いたレングスを取ればよい。という事になります。

たとえば、A1セルに「・」で表現した箇条書きがあり、A2セルに個数を表現する場合、以下のとおりです。

=LEN(A1)-(LEN(SUBSTITUTE(A1,"・","")))

2010年7月25日日曜日

[Excel]ミリ秒を時分秒に変換する

ログの解析などで、ミリ秒⇔時分秒の変換をすることがあります。コレはもちろんマクロを使えば計算できることはわかっていたのですが、マクロを使わずにできないか。と考えて実施してみました。
Excelの時分秒のシリアル値から、以下の計算方法にて実現してみました。

たとえば3分をmsであらわすと、180,000msになります。それがA1に入っているとすると、
=A1/86400000


となります。この計算で出た結果をの表示形式を、「ユーザ定義」とし「hh:mm:ss.0」とすればおk。

2010年7月24日土曜日

[ASP.NET]GACを組み込む方法(VS.NETを使わない)

今はフリーで使えるVWDがありますので、ほとんど出番はありませんが、ASP.NETでは、ASPのように、.aspxにロジックを記述し、実行時にコンパイルし実行するという方法が取れます。
簡単なテストプログラムであれば、こっちのほうが楽かもしれません。

しかし、GACに登録されたアセンブリを使う方法がよくわからず、あきらめてbinフォルダにコピーして実行していた時期がありました。で、先日GACに登録されたインタフェースをテストするために、プログラムが必要となりました。そこには開発環境が無かったので、.aspxのみの構成で実現しようと考えたのですが、GACを使う方法が。。。ということで再度調べてみると、@Registerで指定することができることがわかりました。

今日は時間ないので、コード例はまた今度。

2010年7月21日水曜日

[他]FKのみつけかた(SQLServer)

先日、あまりかかわりのないシステムの環境構築のお手伝いとして、他のDBサーバよりマスタ関係を移行する手伝いをしました。
2つのDBサーバは、一部テーブル構成が異なる(移行先が若干古い)ため、構成の変更を行いました。
その後、リンクサーバを設定し、データを消してからSQLでデータをコピーするという方法をとりました。

で、リンクサーバ設定が完了し、マスタ系のテーブルをTruncateしようとすると、FKがあるので削除不可的なメッセージが表示されました。しかし、あまりかかわりのないシステムであった為、どのテーブルにFKが設定されているのかよくわかりませんでした。

設計書のありかを聞くのも面倒だったし、期待する資料は無い。といわれる可能性があったので、SQLServerにて確認する方法を調べてみると、

 sp_help 'テーブル名'

で調べられることがわかりました。ということで先にFKを設定しているテーブルを削除し、事なきを得ました。

2010年7月20日火曜日

[SQL]一時的に制約を無効化する

データ移行などで、一時的に制約を無視したい場合があります。SQLサーバでは、「no check constraint SQLServer」で一時的に制約を無視することができます。制約およびトリガを無効にする

制約に沿わないデータが合ったとしても、制約を元に戻せます。そのため、データ登録後整合性のチェックをする必要がありそうです。

2010年7月16日金曜日

[Ecxel]0を表示しないようにする

Exceで値が0の場合、自動的に表示しない(見えないようにする)ようにするには、条件付書式設定を使えばいいのですが、その他の方法として、[オプション]→[表示]→ゼロ値(Z)のチェックをはずすことにより、全体的に0を表示しないようにできるようです。あぁしりませんでした。

2010年7月13日火曜日

[Excel]Excelの改行コードはLFのみ

Excelのセル内には改行を入れることができますが、その改行コードはLFのみのようです。
知りませんでした。マクロなどで変換や判定する場合は要注意ですね。

2010年7月11日日曜日

[他]SQLServerでテーブルに設定されているインデックスを確認する方法

sp_helpindexという関数を実行すると、テーブルに設定されているインデックスとその種類がわかります。
コードはこんな感じ。

sp_helpindex 't_test01'

--こんな感じで表示される
/*
index_name    index_description    index_keysIX_T_TEST01
nonclustered located on PRIMARY    TEXT1PK_T_TEST01
clustered, unique, primary key located on PRIMARY    ID
*/

2010年7月7日水曜日

[SQL]SqlServerで8000byteを超えるフィールドを扱う

SqlServerで8000byteを超えるフィールドを扱うばあい、varchar(max)と定義すればよいそうです。
知りませんでした。。。

2010年7月6日火曜日

[他]Vista PremiumでもIISが動く?

先日修理に出していたマシンが、昨日かえって来ました。ということで、本日早速Visual Studio(Expressだけど...)をインストールしました。C#とSQLServerをインストールし、VWDをインストールしようとしてところ、「Web PI のダウンロード ページへ」なる見慣れないリンクが。。。

先に進んでいくと、「Microsoft Web Platform Installer」という機能で、さまざまなあアプリケーションを選択し、インストールすることができます。
その中に、IIS関連の項目があり、Vista Premiumのこのマシンでも選択することができたので、そのままチェックしてインストールすると、「インターネット インフォメーション サービス (IIS) マネージャ」がインストールされていました。

まだ試していませんが、IISが動作する感じがします。
もしかしらたレガシーASPも動作するかも。。。

2010年6月30日水曜日

[.NET]結果的にネットワークドライブから.NETアプリを起動していた

先日、マシンの変更がありました。そのマシンにはDドライブがありませんでした。
でDドライブ想定で環境設定されたシステムの開発を実施してたため、適当なディレクトリに対してネットワークドライブを設定してその場をしのいでいました。

そしてコンパイルしていざ実行してみるとセキュリティーがらみのエラーが。。。
ローカルのドライブでもネットワークドライブはネットワークドライブなので、セキュリティーの制約に引っかかることがわかりました。コマンドのsubstでドライブを設定すればよかったんだろうか?

デバッグはできていたので不思議に感じていたのですが、デバッグの際はCドライブからのパスで動作していることに気づきました。あぁがっかり。

2010年6月28日月曜日

[SQL]16進数でデータを表現する

先日、とあるシステムのテストをしました。DBはSQLServeを使っています。
そのシステムで採用されている開発言語では、varcharフィールドにSQLでデータを登録・更新する際、正しいレングスを設定しないと問題が発生します。

結果的に言うと、短めに設定された場合文字列が切れてしまい、長めに設定すると文字列の後ろに0x00が設定されるというものでした。
それを知らずに、後者のような障害があったとき、最初varcharなのに後ろにスペースがつくなんて。。。
と思って16進数で表示してみると0x00であることがわかりました。コードはこんな感じ。

declare @hoge varchar(10)  
set @hoge = '123abc'

print convert(varbinary, @hoge)

2010年6月22日火曜日

[他]100,000アクセス

このblogを書き始めて2年半が過ぎました。
アクセスカウンタを置いたのが、2008/4。それから2年3ヶ月。今日で10万件のユニークユーザの訪問になりました。

ほとんどが検索エンジンからのアクセスだと思いますが、少しは社会のお役に立てたかのかなぁと思います。
これからも、社会に何かしら還元できますよう、がんばりたいと思います。

2010年6月20日日曜日

[.NET]C#の文字列に@をつける

C#で、文字列定数に@をつけることにより\(円マーク)などのエスケープをエスケープ?することができます。
まぁその程度だと思っていたんですが、なんと、改行コードなどもそのまま取り込めるというのを最近知りました。コレを「逐語的リテラル文字列」というらしいです。詳しくは2.4.4.5 リテラル文字列を参照。

2010年6月17日木曜日

[他]SQLServerでテーブル単位のディスク使用量を得る

無茶な見積もりを要求されることは多々あります。先日前の席に座っている人が「テーブル単位でどれくらいのディスク容量を使っているか教えてくれ!」って偉そうな人に言われていました。
周りの人は目を合わせないようにしていました。えぇまぁ私もその一人です。「そんなの無理無理」って思っていたんですが、SQLServerでは、sp_spaceusedっていう関数が用意されており、なんとテーブル単位でデータの使用量、インデックスの使用量がわかるみたいなんです。

見積もりを依頼された場合、それだけデータを突っ込んで実測したほうが、見積もりするより楽かもしれませんね。

2010年6月12日土曜日

[他]プロセス起動したあと、しばらくすると処理がとまってしまう?

先日、隣の人が、VBSでプロセスを起動していました。
開発は順調に進み、単体テスト、結合テストと順調に進みました。で、性能試験を実施していると、アプリケーションから応答が無くなってしま現象が発生していました。

で、話を聞いてみると一定の件数になるととまってしまう。というものでした。そしてCPUに負荷がかかっていない。
過去に同じような経験が。。。で、よくよく調べてみると、そのプロセスは標準出力に結果を出していることがわかりました。とりえず、標準出力を読み捨ててみては?とアドバイスすると、ビンゴでした。

起動したプロセスは、標準出力をクリアしないと、バッファの出力待ちをしてしまいます。結果アプリケーションがハングしているように見えるという悲しい現象があるんです。ということを思い出しました。

2010年6月7日月曜日

[他]SQLServerでキャッシュをクリアする

SQLの性能評価をしていると、1発目は遅いけど、2度3度と実行していると結果がキャッシュに乗ってしまい、実測するのにSQLServerを再起動。みたいな事をやっていました。
厳密になら、OS再起動なのかも知れませんが、キャッシュにあるかどうかが問題の場合、以下のT-SQLでキャッシュをクリアすることができます。

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE


DBCC (Transact-SQL)の「メンテナンス ステートメント 」に説明がありますねぇ。
ほかにも魅力的なステートメントが。。。今度しらべてみよーっと。

2010年6月4日金曜日

[.NET]想定外の例外の集約処理

想定できる例外(たとえば、型変換の例外/SQL発行時の例外)に関しては、できるだけ狭いスコープで例外処理をすると思いますが、メモリ不足など、想定外のエラーが発生した場合、個別で例外処理というわけには行きません。そういうときに、例外を集約処理します。で、WindowsFormの場合、Application_ThreadExceptionを使います。コードはこんな感じ。

private void Form1_Load(object sender, EventArgs e)
{
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
}

void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    System.Diagnostics.Debug.WriteLine(e.Exception.Message);
}

2010年6月1日火曜日

[他]VS2010のインテリセンスが英語に!!

先日、VB6コンバータを使いたいため、VB.NET2008を入れなおしました。
で、まぁそれはそれで、事なきを得ました。

で、今日、ツールの修正をしようと思ってC#2010ExpressEditionで開発を始めると、インテリセンスが英語になってるじゃないですか。こんな現象が2008でもありましねぇそういえば。
とりあえず、C#2010ExpressEditionをインストールしなおすと、インテリセンスは日本語に戻りました。

2008のように、SP待ちにならずで、よかった。

2010年5月31日月曜日

[他]SQLServerの使用メモリに上限を設定する

SQLServerでは、メモリがあいていればあいているだけ使っちゃいます。しかし単体UPまでは開発とSQLServerを同じマシンに入れておいたほうがほかの人に影響することなく作業ができます。
とはいえ放置しておくと、SQLServerがメモリを食い尽くしてしまうという残念な現象が発生してしまいます。

何とかならないものか。。。と調べてみると、SQLServerではメモリ使用量の上限を指定することができるというのを最近知りました。
SQLServer2008Expressの場合、[サーバのプロパティ]→[メモリ]→[最大サーバメモリ]で上限を指定することができます。個人的な感触ですが、256MBも割り当てておけばほぼ十分ですね。

2010年5月29日土曜日

[他]VB.NET2010Express Editionのコンバーター

VB6の旧システムがあり、ライセンスの都合から古いVisualStudioが入れられないため、VB.NET2008 Express Editionを入れていました。動作させようとは思っていませんが、VB.NETへのコンバータを使用しコンパイルすることにより、検索機能や定義に移動など、統合環境のさまざまな恩恵を受けることができます。

で、機能的にほぼカバーできていることもわかったので、先日VB.NET2010 Express Editionに入れ替えました。

現在も、VB6のシステムを時々手直しすることがあり、時々改訂版が展開されます。
で、今日ですが、VB6のプロジェクトをVB.NET2010でコンバートしようとしたのですが、プロジェクトを開くことができませんでした。で、調べてみると、VB.NET2010 Express EditionではVB6からの変換をサポートしなくなったことがわかりました。

がっくりしながら、VB.NET2008をいえれなおしました。そしてVB6→VB.NET2008→VB.NET2010という変換作業をしました。

VB6をサポートしている奇特な方で、Express Editionしか入れられない少数派の方。ご注意を!

2010年5月24日月曜日

[他]VWD2010のエディットコンティニュ

先日、Webアプリを調査する機会があったので、VWD2010でそのプロジェクトを読み込み、形式を変換。で、早速デバッグ。快適に動作しました。

デバッグ実行しながら動作確認をしていたのですが、一部環境がそろわず、仕方なくコメントアウトしようとしたのですが、「デバッガが既に実行されているプロセスにアタッチされているとき・・・」のようなメッセージが出て、エディットコンティニュできず。

で、いろいろ調べてみました。
  • web.configの設定→debug=trueになっている
  • コンパイル→デバッグモードになっている
  • コンパイルオプション→デバッグ情報を生成はFULLになっている
  • デバッガー→ASP.NETにチェックあり

よくわからずあきらめかけていると、[プロパティ]→[Web]で、「VisualStudio開発サーバを使用する」のほうには、「エディットコンティニュを有効にする」というチェックボックスがあり、開発サーバで動作するように設定してみると、エディットコンティニュが機能しました。

VWDの場合だけかもしれませんが、IISで実行するばあい、エディットコンティニュを使いたければ開発サーバを使う必要があるのだろうか。。。

2010年5月20日木曜日

[.NET]ファイルをいろんなモードでオープンする

先日、「Windowsではファイルを共有モードでファイルを開けない」って言っている人がいました。そんなわきゃーないってわかってましたが、面倒だったので「はぁそうですかぁ」と答えました。

というわけで、ヤってみました。そのおっさんには内緒。コードはこんな感じ。


private void button1_Click(object sender, EventArgs e)
{
    //using System.IO;
    //FileShare.ReadWrite→共有モードでオープンできる
    //FileShare.Read→他のプロセスは読み込み専用ならオープンできる
    //FileShare.Write/None→排他モードになる。他のプロセスはオープンエラーになる。
    using (StreamReader sr = new StreamReader(
            new FileStream(@"C:\temp\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
    {
        string s = sr.ReadToEnd();
    }
}

2010年5月7日金曜日

[他]VS2010Expressは評価目的?

ちょっと前の話ですが、4/28にVS2010のExpressがダウンロード(Webインストール)可能になりました。
昨日気がついたのですが、今日早速ダウンロード。

とりあえずVB.NET2010のみインストールしてみました。
.NET Framework4をインストールしていなかったせいか、2回も再起動を要求されました。

インストールも終わり、起動してみると、スプラッシュウインドウに「評価目的に限ります」の表示が。。。
2008までは商用利用も可能だったのに。と愕然としました。
が、調べてみるとライセンス登録すると、該当の表示は消えるようです。いやーコレで、2008から2010に乗り換えようかなぁという気になりました。

2010年5月2日日曜日

[Excel]文字列をコードにする式

先日、Excelで文字列から文字コードを得たい。と思って調べてみました。もちろんマクロを使えばできるのは知っていましたが、式で何とかできないかと思って。マクロ入れるとあのダイアログが出ちゃいますから。

で、結局「=code("x")」で答えが出ることがわかりました。いやー調べてみるもんですねぇ。

2010年4月21日水曜日

[他]SQLServerの最大容量仕様

以前SQLServer2000の時代、ADO.NETから長いSQL(whereのin条件をたくさん書いている)を実行し、8000byte付近を越えるとエラーになって困っている人がいました。
それを聞いたとき、「そんなSQLって...。作りがおかしい」と思っていました。それは今も変わりません。

アレから、数年たちました。SQLServerも2008にバージョンがあがりました。で先日「はて、今はどれくらいの長さのSQLが投げれるんだろ?」とおもい調べてみました。
調べてみるとSQL Server の最大容量仕様のバッチ サイズがソレにあたります。「65,535*パケットサイズ」って書いてあるんですが、パケットサイズは標準で4KBなので、262,140KBまでいける?ってことでしょうか。
・・・何か勘違いしている気が。。。

とはいえ、INSERTをバッチクエリで処理したい場合、相当長い文が投げれることになります。
パフォーマンス的には効果が出そうですね。

2010年4月20日火曜日

[他]コーディングと単体テスト

製造工程の作業といえば、「コーディング→コンパイル→単体テスト」です(私的には。ですが)。
合っているかどうかは別として。。。ですが、今までやって来た開発は「コーディング→コンパイル→疎通→単体テスト」で、疎通という工程を加えていました。コレは生産物がある程度動作するレベルにあることの確認と、量産時に不具合入りのコードをコピーされないようにするという目的もあります。

いま私の携わっているプロジェクトでは、疎通を実施していません。また、コーディングと単体テストの担当が異なることが多く、動かしたらいきなりエラーみたいな場合があり、現場は大混乱状態。。。

私なら。。。ですが、多少の負担が合ったとしてもコーディング担当が疎通まで実施し、単体テスト担当に引き渡したい気がしますが、一般的にどうなんでしょう。よくわかりませんね。

2010年4月15日木曜日

[.NET]C#の割り算

先日、割り算を実施し小数点以下2桁で四捨五入する。という仕様の処理をテストしていました。しかしどのパターンでも小数点以下の結果が入らず、テストNGとなりました。
で調べてみると、演算対象の両方の値がint同士であることがわかりました。C#ではint/byte/long同士の割り算では、結果が切り捨てられてしまいます。

ということで、片方をdoubleでキャストし、割り算をした結果、想定どおりになりました。
めでたしめでたし。・・・こういうのって、言語仕様を知らないのは、技術者として罪のような気がしました。

2010年4月13日火曜日

[.NET]各言語での演算子の違い

歳のせいでしょうか?実力でしょうかわかりませんが、C#でいうinstanceofってVB.NETでは???...。ということがしばしばあります。
というわけで、困ったときに各言語の演算子の比較を見れば。というのを備忘録代わりにメモ。

2010年4月9日金曜日

[.NET]キャストとASの違い

C#では型をキャストする方法として、(型)によるキャストとASによるキャストがあります。
両方をキャストと表現して良いのかよくわかりませんが、どう表現してよいのかわからないので、以下、キャストと表現します。

違いがよくわからなかったので、C時代から使っているキャストを使っていました。で調べてみると、以下のような違いがあることがわかりました。

  • (型)によるキャスト:型が異なると例外
  • ASによるキャスト:型が異なるとNULL


まぁそもそもキャストすると言う行為自体がアレなんですが、ASにしておけば引数がNULLの場合と型が異なる場合をNULLかどうかで判定できます。
パフォーマンス的にどちらが良いというのは不明ですが、例外処理は基本的に重たいので、おそらくASのほうがよいと考えられます。その辺も含め、両方の処理が同じであればASのほうがいいのかもしれませんね。

2010年4月6日火曜日

[他]SQLServerのSQL実行時間(SET)

GDD Blog: [他]T-SQLでSQLのミリ秒単位で時間を計測するでSQLServerの実行時間のとり方を紹介しましたが、SET文でも同様のことができることがわかりましたので紹介します。
STATISTICS PROFILEのほうは、プロファイルを取得する方法です。ついでに紹介。

SET STATISTICS PROFILE ON;
SET STATISTICS TIME ON;


で調べていると、SET オプションの一覧がありましたので、これもついでに紹介します。

2010年3月30日火曜日

[.NET]SqlParameterのパラメータ追加

ADO.NETではプレースホルダを使う場合、たとえばSqlCommand.Parameters.Addします。
しかし、このAddでは、値をセットすることができず、面倒でわかりづらいコードを書く必要がありました。

で、最近発見したんですが、AddWithValueというのが.NET Framework2.0以降で追加されたようです。
コレ使えばそんな問題はなくなりますね。

2010年3月28日日曜日

[他]SQLServerの排他制御

SQLServerはトランザクションをかけると、共有ロックになります。

  • 更新ロック:他のトランザクションからUPDATE, DELETE不可
  • 排他ロック:他のトランザクションからSELECT,UPDATE, DELETE不可


先日、SQLServerで排他制御の実験をしてみました。実施すると、まさしく共有ロックの動作をしていました。

その方法は、SQL文にヒントをつける方法です。以下の組み合わせで実現します。

■ロックの範囲
  • ROWLOCK:行単位のロック
  • PAGLOCK:ページ単位のロック
  • TABLOCK:テーブル単位のロック


■ロックの方式
  • READPAST:ロック行をスキップして取得する(SELECTだけ)
  • UPDLOCK:他のトランザクションからSELECT不可にする
  • XLOCK:排他ロックを強制的に使用(PAGLOCK・TABLOCKのいずれかも指定)


たとえば、ORACLEのFor Update相当にしようとすると、こんな感じ。

SELECT * FROM T_HOGE WITH (ROWLOCK, UPDLOCK)


ほかには、ISOLATION LEVELを変更する方法があるらしいですが、コレは別途整理したいと思います。

2010年3月23日火曜日

[SQL]特定の条件に一致するテーブルの内容を表示する

以前、マスタのみデータを抜きたいということがあり、1000件以下のテーブルのみ、内容の一覧を取得するSQLを書きました。件数の一覧を取るSQLの応用ですが、備忘録代わりにメモ。

--一時変数(結果格納用)
CREATE TABLE #TEMP_TABLE(
     T_NAME varchar(128)
    ,T_CNT int
)

--sp_MSforeachtableでユーザテーブル全部をループ処理
EXEC sp_MSforeachtable  @command1 ='INSERT INTO #TEMP_TABLE;SELECT ''?'' as T_NAME ,COUNT(*) as T_CNT FROM ?'


DECLARE @QUERY nvarchar(128--SQLの一時領域
DECLARE @NAME nvarchar(128--テーブル名一時領域
DECLARE @CNT int --カウント結果

--カーソルの宣言。このSQLの条件を変更することにより、テーブルを絞り込める
DECLARE cs CURSOR FOR
    SELECT T_NAME FROM #TEMP_TABLE WHERE T_CNT > 1 ORDER BY T_NAME

--カーソルのオープン
OPEN cs
FETCH NEXT FROM cs
    INTO @NAME
WHILE @@FETCH_STATUS = 0
BEGIN
    --SELECTを実行する
    PRINT '※※※※' + @NAME 
    SET @QUERY = 'SELECT * FROM ' + @NAME
    EXEC(@QUERY)
    FETCH NEXT FROM cs INTO @NAME
END

CLOSE cs
DEALLOCATE cs

--一時テーブルを削除する
DROP TABLE #TEMP_TABLE

2010年3月19日金曜日

[.NET]知らなかったコレクション(NameValueCollection)

今日は、NameValueCollectionです。このクラスは、1つのキーに対して、複数の値を保持する機能をもつクラスです。たとえば、部→課の関係や課→課員の関係を簡単に作りたいとき便利ですね。でコードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.Collections.Specialized;
    NameValueCollection collection = new NameValueCollection();

    collection.Add("第1事業部""1課");
    System.Diagnostics.Debug.WriteLine(collection["第1事業部"], "第1事業部");
    //「第1事業部: 1課」と表示される

    collection.Add("第1事業部""2課");
    System.Diagnostics.Debug.WriteLine(collection["第1事業部"], "第1事業部");
    System.Diagnostics.Debug.WriteLine(collection.GetValues("第1事業部")[0], "第1事業部[0]");
    System.Diagnostics.Debug.WriteLine(collection.GetValues("第1事業部")[1], "第1事業部[1]");
    //「第1事業部: 1課,2課」と表示される
    //「第1事業部[0]: 1課」と表示される
    //「第1事業部[1]: 2課」と表示される
}

2010年3月13日土曜日

[.NET]知らなかったコレクション(ObservableCollection)

今日はObservableCollectionです。このクラス、コレクションに追加削除変更などあると、通知する機能があります。なんとかマネージャ的な用途に使えそう。
よくわかりませんがWPF系のプロジェクトじゃないと使えないらしい。WindowsFormのプロジェクトでは出てきませんでした。というこで、コードは感じ。

private void button1_Click(object sender, RoutedEventArgs e)
{
    //using System.Collections.ObjectModel;
    //using System.Collections.Specialized;
    ObservableCollection<MyItem> collection = new ObservableCollection<MyItem>();
    collection.CollectionChanged += new NotifyCollectionChangedEventHandler(collection_CollectionChanged);

    collection.Add(new MyItem() { key = 1, value1 = "111" });
    collection.Add(new MyItem() { key = 2, value1 = "222" });
    collection.Add(new MyItem() { key = 3, value1 = "333" });
    collection.Add(new MyItem() { key = 4, value1 = "444" });

    collection[2] =new MyItem() { key = 5, value1 = "555" };

    collection.RemoveAt(2);

    //↓のように表示された
    //action=Add NewItems=key=1 
    //action=Add NewItems=key=2 
    //action=Add NewItems=key=3 
    //action=Add NewItems=key=4 
    //action=Replace NewItems=key=5 OldItems=key=3 
    //action=Remove OldItems=key=5 

}

void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("action={0} ",e.Action);

    if (e.NewItems != null && e.NewItems.Count > 0)
    {
        sb.AppendFormat("NewItems={0} ", e.NewItems[0]);
    }
    if (e.OldItems !=null && e.OldItems.Count > 0)
    {
        sb.AppendFormat("OldItems={0} ", e.OldItems[0]);
    }


    System.Diagnostics.Debug.WriteLine(sb.ToString());
}

/// <summary> 
/// コレクションに格納するクラス 
/// </summary> 
public class MyItem
{
    public long key { getset; }
    public string value1 { getset; }
    public string value2 { getset; }
    public string value3 { getset; }

    public override string ToString()
    {
        return string.Format("key={0}", key);

    }
}

2010年3月10日水曜日

[.NET]知らなかったコレクション(ReadOnlyCollection)

知らなかったコレクション第二段。ReadOnlyCollection。ん?どっかで使ったことあるような。。。
このクラスは、ListをReadOnlyにしてくれます。更新しようとするとコンパイルエラーになります。
面白いですね。使い方はこんなかんじ。

//using System.Collections.ObjectModel;

List<string> list = new List<string>();
list.Add("111");
list.Add("222");
list.Add("333");
list.Add("444");

ReadOnlyCollection<string> roList = new ReadOnlyCollection<string>(list);
//↓コンパイルエラー
roList[2] = "hoge";

2010年3月4日木曜日

[.NET]知らなかったコレクション(KeyedCollection)

先日何気に、MSDNを見ていると、使ったことがないコレクション系のクラスをいくつか見つけました。
ということで今回はKeyedCollection。
格納したい情報の中にキーが含まれる場合に、キーを個別に設定するのではなく、格納するオブジェクトの中に含まれるプロパティを使う。というものです。コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    MyKeyedCollection collection = new MyKeyedCollection();
    collection.Add(new MyItem() { key = 1, value1 = "111" });
    collection.Add(new MyItem() { key = 2, value1 = "222" });
    collection.Add(new MyItem() { key = 3, value1 = "333" });
    collection.Add(new MyItem() { key = 4, value1 = "444" });

    System.Diagnostics.Debug.WriteLine(collection[2L].ToString());

    //「key=2, value1=222, value2=, value3=」と表示された。
}

/// <summary>
/// KeyedCollectionの実装 
/// </summary>
public class MyKeyedCollection : KeyedCollection<long, MyItem>
{
    public MyKeyedCollection() { }

    /// <summary>
    /// 指定した要素からキーを抽出する
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    protected override long GetKeyForItem(MyItem item)
    {
        // キーの値を返却する.
        return item.key;
    }

}

/// <summary>
/// コレクションに格納するクラス
/// </summary>
public class MyItem
{
    public long key { getset; }
    public string value1 { getset; }
    public string value2 { getset; }
    public string value3 { getset; }

    public override string ToString()
    {
        return string.Format("key={0}, value1={1}, value2={2}, value3={3}", key, value1, value2, value3);

    }
}

2010年3月3日水曜日

[.NET]WebBrouserコントロールにXMLを表示する

先日WebClientでXMLを取得し、WebBrouserに表示するサンプルを作成していました。
WebBrouserのDocumentTextに取得したテキストを設定するだけで、HTMLはそれらしく表示することができました。で、ためしにXMLを表示してみると、HTMLのように表示されてしまいました。IEでのXML表示のようなることを期待していたのですが。。。

直接、NavigateメソッドでXMLのあるパスをさしてみると、IEのように表示されました。

で、取り合えず、WebClientで取得したXMLをローカルファイルに保存して、NavigateにURIで引き渡すと、IEのように表示されました。とりあえず回避できたもののかっこよくは無いですね。何とかしたいんですが、解決策は見つからず。

2010年3月1日月曜日

[他]スキーマ定義のシンタックス

以前、GDD Blog: [.NET]CSVデータを操作する(OleDb)(その2) で、schema.iniについて少し触れましたが、参考になるページを見つけました!。備忘録代わりにメモ。

方法 : スキーマ定義をテキスト ファイル データ ソースに追加する

2010年2月23日火曜日

[.NET]乱数を扱う

.NET Frameworkでは乱数を発生させる仕組みとして、Randomというクラスが提供されています。
しかし、このRandomというクラスは、Donald E. Knuth の乱数ジェネレータ減算アルゴリズムに基づいています。・・・アルゴリズムの詳細はよくわかりませんが、なんでもある演算とシード値(引数)を使って擬似的な乱数を生成するようです。
擬似乱数であるため、完全ではないようで、完全な乱数?するには、.NET Frameworkでは、RNGCryptoServiceProviderというクラスが用意されています。
このクラスは、乱数ジェネレータ(Random Number Generator) の実装らしく、Randomよりは正確な乱数を生成することができるようです。で、使ってみました。コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.Security.Cryptography;

    //32bitの数値用に4byteバッファを確保
    byte[] bytes = new byte[4];

    //暗号乱数ジェネレータでバイト列を生成
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(bytes);

    //byte列を数値に変換
    textBox1.Text = BitConverter.ToInt32(bytes, 0).ToString();

}

2010年2月15日月曜日

[.NET]refとoutと値渡し

私は、VOではない引数を更新するインタフェースがキライです。とくにVB.NETで、ByRefを見かけるとイラっときます。というのも、実行結果はメソッドの戻り値である。という考え方をするからです(あくまで個人的見解です)。値更新の流れを1方向にすることにより、全体的に見通しがよくなる気がします(あくまで個人的見解です)。

しかし、参照渡しと値渡しの違いはわかるんですが、refとoutの違いがよくわかっていませんでした。というわけでちょっと調べてみました。私の理解では以下のとおりです。

 ref:C++でいう参照渡し。呼び出し側でインスタンス生成する必要がある
 out:C++でいうポインタ渡し。呼び出し側でインスタンスの生成が不要

メリットとしては、値渡しの場合、コピーのコストが発生する場合があります(値型の場合だけだっけか?)そういう場合は効果があるかもしれません。
データは汚れるかもしれませんが、基本的にポインタ的な情報のやり取りになるはずなので。

2010年2月13日土曜日

[Silverlight]ASP.NETからのマイグレーション

ASP.NET1.1/.NET Framework1.1の仕事を最初にやってから、5年ほど経過した気がします。
で、過去の経緯から考えた場合、そろそろハードのリース切れのタイミングでもあり、こんな時代じゃなければ、システム再構築や変更の仕事の引き合いがきてもおかしくない時期にさしかかってきました。

今、何も考えずにやっても良いよ。となった場合、おそらくASP.NET2.0 or Silverlight + .NET Framework3.5という選択になると思います。ASP.NETを選ぶのであれば、ajax系の仕組みを組み入れることになるでしょうか。

しかし、依存関係から、サーバのOSが変えられそうにないお客様がいくつか思い当たり、その場合どうするかを暇つぶしに考えて見ました。
ajaxでもいいのですが、ASP.NET1.1系で利用できるAJAX Control Toolkitって聞いたこと無い?と思うので別の。。。というとクライアントのUIはSilverlight で、サーバはASP.NET1.1/.NET Framework1.1でasp.netで使っている機能を流用してWebサービス化すれば。。。

・・・えぇまぁ、きてませんよそんな仕事は。

2010年2月2日火曜日

[.NET]C# 静的コンストラクタ

いっつも「あれーどうだっけ?」となってしまう、C#の静的コンストラクタを備忘録としてメモ。

public class Class1
{
    /// <summary>
    /// 静的コンストラクタ。クラス名を同じメソッド名で、static以外の修飾をしない
    /// </summary>
    static Class1()
    {
        //ここに実装
    }
}


あとはMSDN。静的コンストラクタ (C# プログラミング ガイド)

2010年2月1日月曜日

[TOOL]Home Edition(IISの動作しないOSで)ASP.NETの動作確認をする方法

2年ほど前、とくに何も考えず、VistaのPremiumを買ったこともあり、うちのマシンではIISが動きません。
まぁ家でWeb系の開発したければVWD使えば良いし。と思っていたのですが、単に動作だけを見たいときに、VWDを起動するのが億劫になるんですよねぇ。
で、調べてみると、VWD搭載されている開発サーバを単独で動作させる方法が紹介されていました。
VS 2005やIISを使用せずにWebアプリケーションを実行するには
これは2005の例ですが、2008で同様のことができます(2008ではWebDev.WebServer.exeの格納されているフォルダが異なります)。
 

2010年1月27日水曜日

[TOOL]C#のデバッグ終了が遅い

いつからかわかりませんが、Visual C#のデバッグが終了するのが異常におそく、デバッグするのが億劫になっていました。
会社ではこんなこと無いので、ちょっと調べてみると、
[ツール]→[オプション]→[環境]→コンテンツをダウンロードする間隔(D)をオフにするとOK。的な情報を見つけました。で設定変更してみるとすいーっと終わるようになります。チョー快適。

ファイル更新後の保存時 (Ctrl+Sなど) にCPU使用率が最大となり、しばらく操作不能となる 」とか「Visual Studio 2008でデバッグ終了後、編集可能になるまでに時間がかかる場合は?」に詳細が記載されています。

[SQL]SQL文を最速にする11のポイント

先日、なにげにニッケイのサイトをみていると、SQL文を最速にする11のポイントという記事を発見しました。

基本的なことが、わかりやすくかいてあります。他連載も興味深い。備忘録としてメモ。

2010年1月26日火曜日

[TOOL]Spy++っぽいツール

先日、Visual Studioに付属のSpy++が使いたい用件がありました。しかし、ライセンスの都合上ExpressEditionを使っていたため、Spy++が付属していません。
途方にくれていると、UISpyなるツールがWindowsSDKに付いているとの情報をキャッチ。SDKはインストール済みなので、早速インストールフォルダを確認してみると、それらしいツールはありませんでした。

で、情報を探してみると、SDKでも↓のバージョンじゃないと入っていないらしいとのこと。

Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1

現在、確認中。

2010年1月22日金曜日

[ASP.NET]状態管理に関する推奨事項

ASP.NETでは状態管理のしかたとしてApplication > Session > Requestの順で、広いスコープでデータを管理します。それ以外に、Cookieがあります。でそれらの使い分けについて、まとめられているページを見つけました。備忘録としてメモ。「ASP.NET の状態管理に関する推奨事項

2010年1月15日金曜日

[.NET]シャローコピーとディープコピー

objectクラスにはMemberwiseCloneというメンバ変数をコピーしてくれるメソッドが標準で搭載されています。しかし、このメソッドはシャローコピーなので、内包しているクラスがある場合、そのオブジェクトをコピーしません。
で、コレを解決するにはディープコピーするしかないのですが、コレを簡単にやる方法としてシリアライズする方法があります。意外と簡単。コードはこんな感じ。


//using System.IO;
//using System.Runtime.Serialization.Formatters.Binary;
private void button1_Click(object sender, EventArgs e)
{
    CopyTest test1 = new CopyTest();
    System.Diagnostics.Debug.WriteLine(test1);
    //『IntData=[1] ,StringData=[1], modeText[葉]』と表示される
    test1.SetChild();

    // インスタンスをコピーする
    CopyTest test2 = test1.Clone();
    CopyTest test3 = (CopyTest)Clone(test1);

    System.Diagnostics.Debug.WriteLine(test1);
    System.Diagnostics.Debug.WriteLine(test2);
    System.Diagnostics.Debug.WriteLine(test3);
    //『IntData=[1] ,StringData=[1], modeText[枝]{IntData=[1] ,StringData=[1], modeText[葉]}』と表示される
    //『IntData=[1] ,StringData=[1], modeText[枝]{IntData=[1] ,StringData=[1], modeText[葉]}』と表示される
    //『IntData=[1] ,StringData=[1], modeText[枝]{IntData=[1] ,StringData=[1], modeText[葉]}』と表示される


    // Childのインスタンスがシャローコピーなので、test1/test2のIntDataが同じ値になる
    test2.Child.IntData = 3;
    System.Diagnostics.Debug.WriteLine(test1);
    System.Diagnostics.Debug.WriteLine(test2);
    //『IntData=[1] ,StringData=[1], modeText[枝]{IntData=[3] ,StringData=[1], modeText[葉]}』と表示される
    //『IntData=[1] ,StringData=[1], modeText[枝]{IntData=[3] ,StringData=[1], modeText[葉]}』と表示される

    // test3はディープコピーになるので、IntDataは1のまま
    System.Diagnostics.Debug.WriteLine(test3);
    //『IntData=[1] ,StringData=[1], modeText[枝]{IntData=[1] ,StringData=[1], modeText[葉]}』と表示される

}

private static object Clone(object obj)
{
    object result = null;

    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, obj);

        ms.Position = 0;
        result = bf.Deserialize(ms);

    }

    return result;
}

[Serializable()]
public class CopyTest
{
    public int IntData { getset; }
    public string StringData { getset; }

    private string modeText = "葉";

    public CopyTest Child { getset; }

    public CopyTest()
    {
        IntData = 1;
        StringData = "1";

    }

    public void SetChild()
    {
        modeText = "枝";
        Child = new CopyTest();
    }

    public override string ToString()
    {
        string result = "IntData=[" + IntData + "] ,StringData=[" + StringData + "], modeText[" + modeText + "]";
        if (Child != null)
        {
            result += "{" + Child.ToString() + "}";
        }
        return result;
    }

    public CopyTest Clone()
    {
        return (CopyTest)MemberwiseClone();
    }
}

2010年1月12日火曜日

[.NET]スレッドに引数を渡す

スレッドを生成する場合、.NET 1.1系では引数を使うことができず、SetDataメソッドで対応していましたが、.NET2.0以降ではParameterizedThreadStart デリゲートを使うことにより、実現できるようです。

しかしThread.Startにも引数付きのものが用意されています。どう違うのかMSDNのサンプルからはいまいち読み取れない。。。

2010年1月5日火曜日

[.NET]コンソールアプリでコンソールを消す

.NETでコンソールアプリを作ると、通常、コンソールを消すことができません。が、p/involeを使うことにより、消すことができます。コードはこんな感じ。なのですが、エクスプローラからダブルクリックすると一瞬コンソールが表示されてしまいます。

class Program
{

    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern bool FreeConsole();

    static void Main(string[] args)
    {
        FreeConsole();
        Thread.Sleep(5000);
    }
}


で、完全に消すと方法としては、WindowsFormアプリにしておいて、Formを表示しないという技がありますが、なんとなく違和感がありますね。

2010年1月1日金曜日

[.NET]プライベートコンストラクタのクラスを強引にインスタンス化する

privateコンストラクタしかないクラスや都合によりprivateコンストラクタからインスタンス化したい場合、Activator.CreateInstanceでは、MissingMethodExceptionが発生してしまいます。
こういう場合、Typeからコンストラクタを取り出し、そこからインスタンス化します。コードはこんな感じ。

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //using System.Reflection;
            MethodBase.GetCurrentMethod();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            Type tp = typeof(PrivateConst);
            ConstructorInfo ci =  tp.GetConstructors(BindingFlags.NonPublic| BindingFlags.Instance)[0];

            object obj = ci.Invoke(new object[] { });

            System.Diagnostics.Debug.WriteLine("Type=" + obj.GetType());

            //「Type=WindowsFormsApplication1.PrivateConst」と表示された
        }
    }

    class PrivateConst
    {
        private PrivateConst()
        {
        }
    }
}