ページ

2009年6月19日金曜日

[WPF] ListBox や ComboBox の各行の見た目にアクセスする

たとえば、ボタンをクリックされたら ListBox の 2行目の背景色を変えたい、なんてことがあったとします。
ListBox のそれぞれの行はたぶん Border とか Rectangle とか TextBlock とかを組み合わせて描かれてるんだと思いますが、そいつらにアクセスして背景色を変えたいというわけです。

Silverlight 編はこちら → 「[Silverlight] ListBox や ComboBox の各行の見た目にアクセスする」

■ WPF の場合
VisualTreeHelper を使って ListBox の頭からビジュアルツリーをたどっていけば各行のビジュアルにもたどり着くことができます。
具体的には、ビジュアルツリーをたどっていくと行数分だけ ListBoxItem が出てきます。
この ListBoxItem の下がそれぞれの行のビジュアルです。

ただ、WPF には直接各行の ListBoxItem を取得する方法が用意されています。

private void Button_Click(object sender, RoutedEventArgs e)
{
var item = this.listBox1.ItemContainerGenerator.ContainerFromIndex(2);
var v = VisualTreeHelper.GetChild(item, 0);
if (v is Border)
{
((Border)v).Background = Brushes.Red;
}
}

ItemContainerGenerator を使えば各行で使われている項目コンテナを取得することができます。
項目コンテナっていうのは ListBox の場合 ListBoxItem のことです。
ComboBox の場合は ComboBoxItem になりますし、TreeView の場合は、、、と、ものによって実際のクラスは違うものになりますので、これらを一般化して項目コンテナと呼ばれています。(英語だと item container。そのまんまアイテムコンテナでもいいように思いますが、MSDN Library では項目コンテナと訳されてました)
ContainerFromIndex() メソッドを使えばインデックスに対応する項目コンテナを取得できますし、ContainerFromItem() を使えば項目 (たとえば ListBox.Items[2] といったもの) に対応する項目コンテナを取得することができます。
ListBox の頭からビジュアルツリーをたどるよりはずっと使いやすいです。
これらのメソッドの戻り値は DependencyObject ですが、もちろん、実際の型は ListBoxItem となっています。

項目コンテナの子ビジュアルを取り出してやれば、それが実際に表示されている要素です。
WPF の ListBox の場合 Border になってるのでそれの Background を変えてやれば 「2行目の背景色を変える」 ということができます。
また、もう少しビジュアルツリーをたどると ContentPresenter があります。
データテンプレートを使っている場合などは、この ContentPresenter の下がその内容になっています。

ItemContainerGenerator プロパティが使えるのは ItemsControl クラス、および、その子孫クラスです。
なので、ListBox、ComboBox、TreeView などなどで同じような方法で項目コンテナを取得できるはずです。
ちなみに、WPF Toolkit に含まれる DataGrid も ItemsControl の子孫になってるようです。試してないのでわかりませんが、同じように ItemContainerGenerator を使えるのかもしれません。


2009年6月18日木曜日

[VB10] VB2010 の暗黙的な行継続

昨日書いた 「[VB10] Visual Basic 2010 の新機能」 に関連してちょっとおもしろそうだったので。

Implicit Line Continuation in VB 10 (Tyler Whitney) より
(と言ってもまだよく読んでないんですが)

暗黙的な行継続を認めたとき

Return 1
+foo()

これは Return 1 なんでしょうか?それとも Return 1+foo() なんでしょうか?
2行目は foo() メソッドの呼び出しに単項+演算子が付いたものとも解釈できるわけですね。
C# だとステートメント末に “;” が付くのでこのような曖昧性はおこりませんが、ステートメント末を指定しない VB ではこういったことがおこってしまうわけです。
(C# で +foo(); と書くと 「メソッドの戻り値に単項+演算子を適用した値が何にも使われていない」 ってことで error か warning になったように思いますが、まぁ、それは別の話ってことで)

さらにこんなのも例示されています。

With y
    A=x
    .xfield
End With

さて、これは

暗黙の行継続されてて、こう?
    With y
       A=x.xfield
    End With

それとも書かれてる通り、こう?
    With y
        A=x
        .xfield
    End With

これまたどちらとも解釈可能になってしまいます。

また、VB には Do . . . Loop ステートメント と While . . . End While ステートメント なんてものもあります。
そのため

Do
    While x = 0
        . . .
    End While
Loop

なんてのも Do . . . Loop なのか、それとも Do と While を繋げて Do While . . . なのかがすぐには判断できません。
この場合は、先読みしていって End While が出てくるか Loop が出てくるかといった具合に探していけば曖昧性無しに解釈可能かもしれませんが、いろいろとややこしいことになりそうですし、場合によっては曖昧性が発生するようにも思えます。

上記記事には他の事例も載っていますが、こんな風に VB では 「どこでも改行できる」 なんてことは不可能なわけです。
C/C++/C#/Java と言った言語は 「改行は空白文字の一種」 とみなされて、空白を書けるところであればどこでも改行できます。(もちろん、プリプロセッサや文字列定数の中などは改行は別扱いされたりしますが)
VB の文法をこのように変更することはどう考えても不可能なので、文法的に曖昧性が発生せず、みんなが改行したいだろうと思われるところを抽出し、そして 「ここでの改行は認めよう」 というのをルール化したのが暗黙の行継続という機能なわけですね。


2009年6月17日水曜日

[Silverlight] スプラッシュ・スクリーンを自前のものに差し替える

Splash screens and Loaders in Silverlight より。
xap ファイルのサイズが大きいときなどロードに時間がかかってるときは Silverlight プラグインが自動的にロード中のくるくる回るやつを表示してくれます。
あれって差し替えることができるんですね。

まず、適当な XAML を用意する。
そして、Silverlight プラグインを読み込んでいる <object> タグに

<param name="splashscreensource" value="XAML のファイル名"/>
<param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />

と書きくわえます。
splashscreensource については こちら。
もちろん、onSourceDownloadProgressChanged ファンクションを JavaScript で書いておく必要があります。
xap を読み込んでいる間に表示するためのものですから、Managed で書くことはできないんですね。
onSourceDownloadProgressChanged ファンクションはロード中に適当な間隔で呼ばれるので、XAML を操作してプログレスバーを進めるなり、パーセント表示を進めるなり好きなようにすればいいと。


[VB10] Visual Basic 2010 の新機能

VB10 (VB2010 って言った方がいいんだろうか?) を追っかけてる人には何を今さらっていう話題なんでしょうが、ついさっき知って軽くショックを受けたのでw

VB10 の新機能が What's New in Visual Basic 2010 にあります。

最初の自動実装プロパティは C# に以前からある機能に似てますね。
ただ、C# と違うのは

Public Property Name As String

とすると自動的に _Name という Private なフィールドが作られるそうです。
もちろんコード内で _Name にアクセスすることもできるし、デバッガでウォッチするようなこともできるそうです。ただし、インテリセンスには出ないようになってるとのこと。
C# では予測できない長い名前が生成されるのに比べると考え方がずいぶん違いますね。

続いて コレクション・イニシャライザ。

Dim winterMonths = {"December", "January", "February"}

こんな風に書けると。
C# とほとんど同じですね。というか、VB で { } を使うのってどうなの?という気がしちゃうんですがw
それよりも、Dim が C# の var とほとんど同じ意味だってことがいまだになじまないなぁ。
(上記は As Object() ではなく、きちんと型推論されて As String() になります)

そして暗黙的な行継続。ここ の中ほどの “Implicit Line Continuation”。
ついに VB でも “_” 無しで改行できるようになるんですね。
が、細かいルールがあるようで表になってます。
”_” 無しで改行できるのは

  • カンマ “,” の後。
  • “(“ の後、”)” の前。
  • “{“ の後、”}” の前。
  • XML リテラルの中の “<%=“ の後、”%>” の前。
  • 文字列結合演算子の “&” の後。
  • 代入演算子 (=, &=, +=, <<= など) の後。
  • 二項演算子 (+, ?, Mod, <, <=, And, AndAlso など) の後。
  • “Is” と “IsNot” の後。
  • メンバ名の “.” の後、メンバ名の前。ただし、With ステートメントや初期化リストの中では “_” が必要とかなんとか。
  • XML リテラルの中の “.”、”.@”、”…” の後。ただし、With キーワードの中では “_” が必要とかなんとか。
  • 属性を示す “<” の後、”>” の前。ただし、アセンブリレベルとモジュールレベルの属性のときは “_” が必要。
  • LINQ の “From”、”Order By”、”Select” などの前後。ただし、”Order By” などを途中で改行してはダメ。
  • For Each ステートメントの In の後。
  • コレクション・イニシャライザの From キーワードの後。

だそうです。
うーん、なんと言うか、努力賞ものですね。
まぁ、「ここなら改行して良さそう」 と思えるようなところでは改行して大丈夫みたいなので使う分には混乱は少なそうではありますが。

それと 複数行のラムダ式。

Dim increment1 = Function(x) x + 1
Dim increment2 = Function(x)
Return x + 2
End Function
Console.WriteLine((Function(num As Integer) num + 1)(5))

(複数行なのは 2つ目の increment2 だけですが)
この複数行のラムダ式のときの Function . . . End Function は普通の Function . . . End Function と同じように扱われるから行末に “_” は要らないのかな?
いや、実はラムダ式は式だから行末に “_” が必要だけど、上記の暗黙的な行継続によって “_” を省略できてるだけってことなのかな?

他にも新機能はあるようですが省略。


[.NET] System.Data.OracleClient 終了のお知らせ

ADO.NET team blog : System.Data.OracleClient Update より
えーと、これって 「カスタマーやパートナー、MVP たちと話をし、慎重に検討した結果、ADO.NET に含まれる System.Data.OracleClient は deprecate にすることに決まった」 と書いてありますよね?
ほぉ~、まじっすか。

どうやら
「System.Data.OracleClient は .NET Framework 4.0 にも含まれる。けれども deprecated とマークされる。なので、コンパイル時には warning が出る。ただ、実行する分にはまったく問題無い。Microsoft としては、アプリケーションを新規開発するときには Microsoft の OracleClient ではなく、他のパートナーが提供している ADO.NET プロバイダ for Oracle を使うことを強く勧める」
ということだそうです。

ちなみに、
「.NET Framework 4.0 のサポートポリシーに基づいてクリティカルな問題があった場合はホットフィックスの提供は続ける。.NET Framework 4.0 のサービスパックとしてクリティカルなバグフィックスの提供も続ける」
とあるので、新機能が追加されることはもう無いかもしれませんが、最低限のサポートは継続されるようです。


2009年6月11日木曜日

[WPF][Silverlight] WPF と Silverlight の違いをまとめた文書 (ただし英語)

まだ、中身は見てないんですが。。。

Guidance on Differences Between WPF and Silverlight
CodePrex にこんな文書が公開されていました。
これを書かれたのは Wintellect 社のシニア・コンサルタントの Sergio Loscialo さんみたいです。


2009年6月10日水曜日

[Silverlight] 例外とデータバインディングエラーを見るツール

まだ、ちゃんと読んでないしダウンロードもしてないんですが、覚え書きとして。
Glimpse for Silverlight ? Viewing Exceptions and Binding Errors
ほんのわずか、Application_Startup を書き変えて上げると、

  • 未処理の例外
  • データバインディングの際に出る例外
  • データバインディングのソースを書き間違って該当するソースが見つからないもの

を表示してくれるツールです。(ツールというか、ソースコード)

ダウンロードのファイルの拡張子が .doc になってるけど .zip にリネームして解凍してくれとのこと。


2009年6月9日火曜日

[Silverlight] Silverlight 3 は BinaryHttpBinding もサポート

Improving the performance of web services in SL3 Beta より。

というか、その元になってる 「What's new with web services in Silverlight 3 Beta」 より。
Silverlight 2 の Web サービス呼び出しは BasicHttpBinding だけでしたが、Silverlight 3 では BinaryHttpBinding もサポートされるそうです。
って、BinaryHttpBinding がどういうものなのか良くわかってないんですが、通常の XML 形式の SOAP ではなく、バイナリでやり取りしてしまおうってもんなんでしょう。
おそらく、W3C で規格化されているわけじゃないんでしょうから WCF の独自形式なんだと思います。
なので、相互運用性とかは無くなってしまうんだと思いますが、そんなものは必要くて通信のパフォーマンスをちょっとでもでも上げたいときはなかなか有効な方法だと思います。

あと、Silverlight 2 では Visual Studio の 「Add Service Reference」 で Web サービスのプロキシクラスを生成していましたが、Silverlight 3 では slsvcutil.exe というツールも提供されるそうです。


[.NET] Parallel ループ本体が小さいときの速度アップ法

Achieving Speedups with Small Parallel Loop Bodies より。
イテレーションが小さいときにうかつに Parallel にするとかえってパフォーマンスが悪くなる可能性があります。
例としてこんなコードが載っています。

int[] array = new int[100000000];
Parallel.For(0, array.Length, i =>
{
array[i] = i * i * i;
});

これだと 「array[i] = i*i*i;」 というだけのコードをパラレルにものすごい回数実行するため、パラレルのオーバーヘッドがしゃれにならないくらい大きくなってしまうわけですね。
普通の for ループにしてしまえばパラレルにするオーバーヘッドは無くなりますが、それではスレッド一つしか使わないためもったいないです。

上記の記事では、こういった場合に使える ForRange というちょっとしたメソッドが紹介されています。
ForRange はこんな風に使います。

int[] array = new int[100000000];
ForRange(0, array.Length, (from, to) =>
{
for (int i = from; i < to; ++i)
{
array[i] = i * i * i;
}
});

上記記事に載っているソースコードを見れば明らかですが、ForRange は Environment.ProcessorCount (搭載されているプロセッサ・コア数) 分に分割して Parallel.For を呼ぶようになっています。
仮にプロセッサ・コア数が 4 つの場合は、上記のコードは 0~25000000、25000000~50000000、50000000~75000000、75000000~100000000 の 4 の for ループが Parallel.For されることになります。

なるほどなぁ。


2009年6月8日月曜日

[.NET] Win 7 時代の Windows Automaion API 3.0(?)

Windows Automation API SDK Tools より
スクリーンリーダ (読み上げソフト) に対応したりとかするための Automation ですが、どうやら Windows 7 時代は 「Windows Automation API 3.0」 という名前になるようです。
冒頭部分には以下のようなことが書いてあるように思います。(自信ないんですが)

もう MSAA や UI Automation そのものとは言えなくなってきたから 「Windows Automation API 3.0」 と呼ぶことにした。(MSAA っていうのは Microsoft Active Accessibility 2.0 のことなのかな?)
もはや IAccessible は MSAA 専用ではなく、UI Automation のプロパティなんかもサポートするようになってるし、IAccessibleEx は MSAA と UI Automation の世界の橋渡しをするようにもなってる。
IUIAutomationLegacyIAccessiblePattern は MSAA のアクセシブル・オブジェクト・ツリーと UI Automation のエレメント・ツリーの間を行き来できるようにする。
MSAA のバージョンナンバーへのリスペクトとして 「Windows Automation API “3.0”」 とした。
それぞれの技術に関して言うときは “MSAA” や “UI Automation” という呼び方を今後もするけど、総称的、もしくは、フレームワークとして言うときは “Windows Automation API” という呼び方をすることになる。

というようなことが書いてあるようです。
MSAA ってのが何なのか、MSAA と UI Automation はどういう関係なのか、なんていう基本的な部分がよくわかってないので、あってるのかどうかイマイチ自信はありません。

記事では、Windows SDK などに含まれているツールについて紹介されています。
また、それぞれのツールが MSAA 用なのか UI Automation 用なのかが表でまとめられています。


[VS2010] 痛 Visual Studio

Visual Studio 2010 が WPF ベースなので痛IDEに出来るのではないかという話
この発想は無かったw
すばらしいwww


2009年6月6日土曜日

[VS2010] Visual Studio 2010 Beta 1 日本語ドキュメント(機械翻訳)

「Visual Studio 2010 Beta1 製品ドキュメント公開のお知らせ」 より
Visual Studio 2010 Beta 1 の日本語ドキュメントが公開されたそうです。
ただし、機械翻訳です。
機械翻訳なんですが、英文と訳文がならんで表示されて、訳文にカーソルを乗せると対応する英文がハイライト表示されます。サイドバイサイドビュー (SxS View) っていうそうです。
これいい!
正規版では人力翻訳になるそうですが、そのときにも SxS View が使えるようにしてほしいです。

VS2010 Beta1 はこちらのURL: http://msdn.microsoft.com/ja-jp/library/fx6bk1f4(VS.100).aspx
.NET Framework 4 はこちらのURL: http://msdn.microsoft.com/ja-jp/library/w0x726c2(VS.100).aspx

ほんのちょっと見ただけですが、なぜか SxS View が無くなっちゃうところもあるみたいですね。ここ とか。
あと、.NET 4 の方は左のツリーと同期が取れてないような。。。

ところで、低帯域幅表示をオンにするとかなり軽くなるので低帯域幅じゃないときも便利だったりしますが、さすがに SxS View は無くなっちゃうんですね。
SxS View のために低帯域幅表示が重くなっては本末転倒なので必要無いとは思いますが、「ベータ版用に機械翻訳されたものです」 という注釈もなくなっちゃうのでそれくらいは入れておいた方がいいような気がします。


2009年6月4日木曜日

[Xbox360] Project Natal の中の人の話

Hands ? and Body ? on with Project Natal より
このブログは Xbox Live Community Team の方のブログで、Project Natal について書かれてました。

どうやら Kudo Tsunoda 氏が作った Project Natal の技術デモを初めて見たときのことのようです。
one-on-one とあるので一対一で見せてもらったみたいです。
やっぱり最初は 「幼い子が部屋の中をかけ回ったら? 猫が足元を横切ったら? 足がテーブルの陰になったら?」 といった疑問があった模様。
で、Kudo 氏が全身を使ったゲームのデモをやったあとに実際に自分もやらせてもらったと。
それは ”It was an amazing experience.” だったとあります。
そして、以下のようなことが書かれてます。

  • コントロールはすごく良く反応したし正確。体を速く動かしても問題無いし、ゲームのアバターもちゃんと付いてくる。ジッター (ブルブル震えるようなことだと思います) やラグもまったく無い。これはまだプロトタイプだということだったけれど、ちゃんと動く、ほんとによく動く。「ファイナルプロダクトに向けて直さなくちゃいけないこと」 なんてゼロだった。
  • Project Natal は赤外線スペクトラムを使っている。普通のカメラを使った技術と違って照明を配置したりといった必要はない。部屋の明かりを全部消して、照明がディスプレイのものだけだったとしても、ゲームをプレーすることができる。
  • The skeleton tracking keeps other objects, people, and creatures from interfering with your onscreen character. (「スケルトントラッキングは画面上のキャラが干渉を受ける他の物体や人、クリーチャーを keep する」 ということだろうけど、keep が良くわからない。続く文章からすると 「他の物体、人、クリーチャーがあってもちゃんと認識してるからスケルトントラッキングし続けることができる」 という意味のように思えるけどそれでいいのかな?)
    部屋にいる誰かが私の前に来て腕を振ったとしても、ノープロブレムだ。だから小さい妹が飛び跳ねたり走り回ったりしても心配する必要はない。
  • センサーは複数のプレーヤーをトラックできる。なので、全身を使って協力しあうようなアクションも OK。
  • This controller allows for some serious, full-body exercise. You’ll get a workout in more than just your right arm. (イマイチわからないけど、「このコントローラは全身運動にも使える。右手だけ動かしてるよりもよっぽとトレーニングになるよ」 みたいなことかな?)

そうか、そんなに反応もいいのか。
しかも、どうやらすでにかなり完成度は高いと。
どんなものが出てくるのか楽しみだなぁ。

ところで、普通のカメラの画像解析と赤外線の奥行き情報とを併用してるのかと思ってましたが、どうやら赤外線のみなんですね。
確かにその方が照明とか気にしなくていいから扱いは楽そうだな。


2009年6月2日火曜日

[Xbox360] Project Natal が楽しそうすぎる

あちこちで取り上げられてますが、
engadget 日本版: 「動画:Xbox 360のモーション操作アクセサリ「Project Natal」発表」
これすごいなぁ。

動画はプロモーションムービーみたいなもんでしょうから、ここまで完璧な認識ができるのかどうかはわかりませんが、それでもかなりできるんでしょうね。
ZCam の解説へのリンクもありますが、なるほど、赤外線パルスで Z 軸の奥行きをピクセル単位で認識してるのか。
そんなことができるんだ。
確かに奥行きの情報があればかなりいろいろなことができるようになりそう。

ところで、これって簡易モーションキャプチャとして使えるようにしてくれないんだろうか?
データを .bvh あたりで吐き出してくれればそれでいいんだけど。
カメラから見て陰になってるところはどうしようもないとか、いろいろと制限はあるとは思うけど、それでもこれでモーションキャプチャできたらかなりおもしろいことになりそう。

Project Natal = Awesome! Could you build your own for Windows 7?
なんかこんな記事が。
本文中には 「(Project Natal を Windows 7 で使うには) モーションをキャプチャしたり 3D 空間のジェスチャを解析したりするドライバを書く必要がある。これは簡単なことではない」 みたいな感じのことが書いてあるんですが。。。
文末の UPDATES のところに 「Project Natal は SDK もあることがわかった。これについはまたわかったときに書く」 みたいなことが書き足してありますね。
この SDK ってのは Windows 用の SDK ってことなんでしょうか?
Windows 上でも誰でも使えるなんてことになったらおもしろいだろうなぁ。


2009年5月29日金曜日

[Silverlight] Silverlight 3 は 7月 10日にローンチ

Silverlight 3 to launch July 10 より
「Microsoft は Silverlight 3 と Expression Studio 3 ファミリーを 7月 10日にサンフランシスコでローンチする予定だと company officials が 5月 28日に語った」
だそうです。

しばらく前から 「7月くらいらしい」 なんて噂はありましたが、どうやらほんとみたいですね。
早いなぁ。
そうすると近いうちに Beta 2 とか来るのかな?

Beta 1 だと TextBox 上で IME をオンにするとまともに文字入力できなくなっちゃったりとかしてたけど、それなりには直ってるんだろうか?(直ってないと困るけど)
正直、あわてなくていいからちゃんとしたものをリリースしてほしいなぁ。


2009年5月28日木曜日

[.NET] Parallel.For ループからとっとと抜ける方法

Exiting from Parallel Loops Early より
普通の for ループでは break と書けば簡単にループから抜け出せます。
んじゃ、Parallel.For や Parallel.ForEach では?とかそういう話。

最初に書いておきますが、いまだに Parallel Extension を使ったこともありませんし、試す環境もないのでブログの記事とかリファレンスとかだけを見た知識で書いてます。
なので、間違ってたらごめんなさい。
というか、間違ってたらぜひ教えてください。

で、上記の記事の前半では例外について書かれてます。
普通のループでは例外が発生しても問題ありませんし、ループの中だろうが外だろうが好きなところで catch できます。
しかし、Parallel ループではそうはいきません。
それぞれのイテレーション (ループの一回分のこと) はどのスレッドで実行されるかは不定ですから例外が外に伝わってくるとは限りませんし、どこかのイテレーションで例外が発生してもループが止まるとは限りません。
んじゃ、どうなるか?
上記の記事によるとどうやら

  • Parallel.For / ForEach 内で例外が出るとランタイムがキャッチする。
  • 例外が出た後は新しいイテレーションを開始しないようにする。
  • ただ、すでに並列に動いているイテレーションは最後まで実行される。
  • 動いている全部のイテレーションが終わったら、発生した例外を全部集めて System.AggregateException にぶち込んで、こいつを throw する。

ということみたいです。
コードで書くと、

try
{
Parallel.For(0, N, i =>
{
throw new Exception("例外");
});
}
catch (AggregateException ex)
{
// ex.InnerExceptions.Count は 2 以上の可能性もある
}

ということだと思います。
あと、一つのイテレーションが長い場合、他のイテレーションで例外が発生したかどうかは ParallelLoopState.IsExceptional で判断できるそうです。
Parallel.For / ForEach には body が Action<int, ParallelLoopState> となっているバージョンもあります。
それを使って以下のように書けるわけです。

Parallel.For(0, N, (i, loopState) =>
{
// いろいろ処理

if (loopState.IsExceptional) { // 他のイテレーションで例外が出てるので終了する return; }
// いろいろ処理 });

続いてループを抜ける件について。
これには ParallelLoopState.Stop() メソッドと Break() メソッドが使えます。
まずは、Stop() メソッドについて。

  • Stop() が呼ばれた後は新しいイテレーションを開始しないようにする。
  • ただ、すでに並列に動いているイテレーションは最後まで実行される。
  • 他のイテレーションが Stop() を呼んだかどうかは ParallelLoopState.IsStopped で判断できる。
  • 動いている全部のイテレーションが終わったら、Parallel.For / ForEach が終了する。
  • Stop() が呼ばれたかどうかは ParallelLoopResult.IsCompleted で判断できる。ちなみに、ParallelLoopResult は Parallel.For / ForEach の戻り値。

ということみたいです。
コードで書くと以下みたいな感じ。

Parallel.For(0, N, (i, loopState) =>
{

if (loopState.IsStopped) { // 他のイテレーションが Stop() を呼んだので終了する return; }

if (終了条件) { // もう終わる loopState.Stop(); return; }
});

続いて Break() です。
これは、http://msdn.microsoft.com/en-us/library/system.threading.parallelloopstate.break(VS.100).aspx を見ると、

  • Break() が呼ばれた後はより大きい数のイテレーションは開始しないようにする。
  • すでに並列に動いているイテレーションは最後まで実行される。
  • 一番小さい数が ParallelLoopState.LowestBreakIteration にセットされる。
  • Break() が呼び出されたかどうかは ParallelLoopState.LowestBreakIteration が null かどうかで判断できる。(ParallelLoopState.LowestBreakIteration は Nullable<long> です)
  • ParallelLoopState.LowestBreakIteration が確定したら、Parallel.For / ForEach が終了する。
  • Break() が呼ばれたかどうかは ParallelLoopResult.LowestBreakIteration で判断できる。

ということみたいです。
ちょっとどう表現したらいいのかアレなんですが、要するに以下みたいなことだと思います。

0~1000 の Parallel.For ループがあったとします。
このうち、100番のイテレーションで Break() を呼んだとします。
すると 101~1000 のイテレーションは実行する必要が無いことが確定します。
また、この時点では ParallelLoopState.LowestBreakIteration に 100 がセットされます。
Parallel ループでは、イテレーションが並列で実行されるだけでなく、どういう順番で実行されるかも不定です。
ですから、0~99 のイテレーションに実行していないものがあるかもしれません。
もしあったらそれらのイテレーションを実行します。
そして、Break() を呼び出すより小さいイテレーションがあったらその数に ParallelLoopState.LowestBreakIteration が更新されます。
こうして Break() を呼び出す最小のイテレーションを求めて、その数が ParallelLoopState.LowestBreakIteration にセットされ Parallel ループが終了します。

どうだろ?
あってるかなぁ?
試す環境が無いのでちょっと自信が無いところもあるんですが、きっとこういうことだと思います。

Parallel Extensions なんてだいぶ前から CTP とか出てたし、最初はこういった解説ぐらいいくらでもあるんだろうと思ってたんですよね。
で、なにげにググってみたら ParallelLoopState だと 36件、ParallelLoopResult だと 6件という、びっくりするような結果で、もちろん日本語のページは一つも無し。
なので試す環境も無いくせに思わず書いてみましたw

あと、Parallel ループの中で気軽に使える ConcurrentQueue、ConcurrentStack なんていうスレッドセーフ版のコレクションも増えてるんですね。
http://msdn.microsoft.com/en-us/library/system.collections.concurrent(VS.100).aspx
これはなにげに便利そうだな。


[.NET] .NET Framework 4.0 での NGen の進化

Improvements to NGen in .NET Framework 4 より
FX 3.5 SP1 で NGen がメジャーチェンジしていたそうです。
その内容については MSDN Magazine の 「CLR Inside Out: CLR Optimizations In .NET Framework 3.5 SP1」 にあるとのこと。
この記事は日本語訳もあります。「CLR 徹底解剖: .NET Framework 3.5 SP1 の CLR の最適化」

この MSDN Magazine の記事によると FX 3.5 SP1 で起動パフォーマンスがかなり向上したとのことですが、ブログの記事によると FX 4 でも起動パフォーマンスの向上を行っているようです。
NGen 関連の改良のようですが、”Best of all, you don’t have to do anything to get these benefits ? they’ll happen automatically when you use .NET 4.” とあります。
これは、「これらの利益を受けるのに何もする必要はないよ。.NET 4 を使うだけでいい」 という意味だと思うんですがあってるかなぁ?
だとすると、NGen.exe を使って自分でどうこうしておかなくちゃいけないとかそういうものではなく、勝手に起動パフォーマンスが良くなるってことですね。
(すべてのアセンブリが自動的に NGen されるようになったというわけじゃないと思うんだけど、どうなんだろう?大量のベースクラスライブラリや GAC に入っているアセンブリが NGen されてるから自然とすべての人に恩恵があるってことなのかな?ちょっとこの辺がよくわからない)

で、ブログの記事では 4つの NGen の進化について書かれています。

  • NGen SxS: CLR が SxS になったので NGen も SxS になった。
  • Multi-proc NGen: NGen がマルチコア/マルチプロセッサを使うようになった。
  • Targeted Patching: 今まではあるアセンブリが変更されるとそれを使用していたすべてのアセンブリを NGen しなおす必要があった。これを、変更が外部に影響しない (メソッドの中が変わっただけでインターフェースは変わっていないなど) 場合は NGen しなおさないようにした、ということみたい。
  • No NGen in partial trust: 今までは部分信頼でもロードできて実行できるイメージを作ってたけど、部分信頼なんて必要無さそうなので FX4 では止めた。もし、部分信頼が必要だっていう人がいたら教えて。といったことが書かれてるみたいだけど、正直この “No NGen in partial trust” の部分については意味が良くわからない。

2009年5月27日水曜日

[VS2010] ボックスセレクションで複数行編集!

The new Box Selection, now with Multi-Line Editing! より
Visual Studio 2010 ではボックスセレクションができるんですね。
↓の動画を見れば一目瞭然です。(英語ですが見りゃわかります)

<br/><a href="http://video.msn.com/video.aspx?vid=3e57917d-1b92-4188-b898-25a1d64a408e" target="_new" title="Box Selection and Multi-Line Editing Demo">Video: Box Selection and Multi-Line Editing Demo</a>

ボックスセレクションは 「Alt キーを押しながらマウスをドラッグ」 って言ってるのかな?

まぁ、テキストエディタなら当たり前にある機能だったりしますけどね。


2009年5月26日火曜日

[Silverlight] ブラウザにログ出力

Silverlight Logging Extension Method より
「Silverlight はブラウザ上で動くので Console.WriteLine() はできません。System.Diagnostics.Debug.WriteLine() は Visual Studio のアウトプットウインドウに出力されます。けど、デプロイした後や VS が無いような場合に簡単にログ出力できません」
てな感じで、そんなときに使える console.log 関数が紹介されています。

Firefox に Firebug が入れてあれば

<script type="text/javascript">
console.log("test");
</script>

なんてすると Firebug の Console に出力されます。
知らなかったんですが、上記の記事によると console.log 関数は IE8 でもサポートされているみたいです。
で、上記記事では console.log 関数を Silverlight から呼び出す方法が紹介されています。

var console = (HtmlPage.Window.Eval("console.log") as ScriptObject);
if (console != null)
{
console.InvokeSelf(obj);
}

Eval で “console.log” を評価させて function を取得してるんですね。
なるほどなぁ。
GetProperty でオブジェクトをたどりながら取得するっていうのが普通の方法じゃないかと思いますが、Eval で評価させちゃうってのは楽チンでいいですね。オーバーヘッドはちょっと大きそうですが。


[VS] Visual Studio Gallery (と、VS2010 のエディタの機能拡張)

New Visual Studio Gallery is Live より

Visual Studio Gallery が新しくなったそうです。
(以前はどういうものだったのか私は知らないんですが)
名前の通り、Visual Studio 向けのプロダクトやエクステンションのギャラリーです。
Visual Studio 2010 向けを中心とするようですが、今見てみたところ 2005 や 2008 向けもあるようです。

それにしても Image Insertion とかおもしろいよなぁ。

Image Insertion はソースの中に画像を置けるようにしちゃう VS2010 用アドオンです。
仕組みについては書かれてないみたいですが、たぶんソースコード上は ”//#[IMAGE:ファイル名]” 見たいな感じでコメントが書かれているだけで、アドオンがそれを読み取って対応する画像を表示するというようなもんでしょう。
これって XML コメントの中にも書けるとおもしろいと思うんだけどどうなんだろう?
(けど、それには Sandcastle 側が対応しないとダメか。そういや Sandcastle は Visual Studio 2010 で統合されてるとかって話だったように思うけど、どうなってるんだろう?)

他にもインテリセンスの表示を WPF ベースにしていろいろと機能追加する IntelliSense Presenter、正規表現を編集したりテストしたりできる Regex Editor なんてのもあります。

実は Image Insertion、IntelliSense Presenter、Regex Editor の 3つは http://editorsamples.codeplex.com/ にある Visual Studio 2010 のエディタを機能拡張するサンプルだったりします。
どうやら VS2010 では結構簡単にいろいろと機能拡張できるようになっているみたいですね。
そのおかげか、タブとスペースを可視化してくれる Reasonable Visible Whitespace、現在行をハイライト表示してくれる Current Line Highlighter といったあるとちょっとうれしいようなものが早くも登録されています。


2009年5月22日金曜日

[VS2010] マネージドコードのダンプデバッグと IL インタープリタ

Virtual code execution via IL interpretation
「Visual Studio 2010 Beta 1 にはマネージドコードのダンプファイルデバッグと今からブログに書くすんげー機能が含まれてるよ」 なんて感じで始まってるんですが。。。

ダンプファイルデバッグっていうのは、「CLR 4.0 advancements in diagnostics」 にクラッシュダンプファイルを Visual Studio で開くとマネージドの状態 (スタックとかローカル変数とか) を見ることができる、とかなんとか書いてあるんですが、つまりそういうことだよね?
うっひゃー、これはうれしいな。

で、
「ダンプデバッグはとても便利だし、長いことリクエストされてた機能だけど、ダンプファイルといっしょにプロセスが生きているわけじゃないので property-evaluation は動かない。property-evaluation はファンクションだとか ToString() だとかプロパティのゲッターだとかが実行されているスレッドをデバッガが乗っ取るっていう仕組みだからね。ダンプデバッグするときには乗っ取るスレッドはもう動いてないし」
なんてことが書かれてます。(超いいかげんな訳)
ようするに、デバッガでプロパティの値を見たりする機能は、対象となるプロセスが動いていることを前提としてるってことなんでしょう。

で、
「ダンプファイルのロードに加えて、ファンクションの IL オペコードをインタープリタで動かして、実行をシミュレートできるようにした。デバッガで結果を表示できるように」
なんてあります。
(原文が太文字になってるところを同じく太文字にした)
おぉ、すげぇ、まじっすか!

簡単なサンプルコードが載ってて、その下に 「Main() の終わりのところで止めて、”Debug - Save Dump As ...” でダンプファイルを書き出して、”File ? Open ? File ...” でダンプを読み込んでみるべし」 とあります。
「普通なら dict, p といったローカル変数と生フィールドが見えるけど、プロパティの内容とか ToString() した値とかは見れない。こんな風にね」
と、キャプチャした画像が載ってます。

「しかし、インタープリタがあれば、実行をシミュレーションできる。ウォッチウインドウを見てみるべし」
ということで、ウォッチウインドウのキャプチャ画像があります。
これの Value の 「Count = 0x00000002*」 のように最後に “*” が付いているのが IL インタープリタによってシミュレーション実行して求めた値だそうです。

以降、「どうやって動いてる?」 とか 「他にできること」 といった解説が続いてます。

うっひゃー、これは確かにすごいや。
なんか他のことにも使えそうな気がする。
ところで、ダンプじゃなく普通にステップ実行するときに IL レベルでステップってできるようになったのかな?
今までってソースの下はすぐ JIT 後のアセンブラだったよね?
IL でステップしてみたいと思うことがあるんだけどな。


[Silverlight] Visual Studio 2010 Beta 1 と Silverlight (Beta 1 でもマルチターゲット可能らしい)

当分、VS 2010 Beta 1 を入れる予定は無いんですが。。。

Silverlight and Visual Studio 2010 Beta 1
Visual Studio 2010 では Silverlight 開発のマルチターゲットと Silverlight のデザイン編集 (XAML を直接書き換えるのではなく) ができるようになります。
で、上記記事によると VS 2010 Beta 1 でもマルチターゲットにできるそうです。
ただし、以下の手順でセットアップする必要があるようです。

クリーンな環境だとして、

  1. Visual Studio 2010 Beta 1 を入れる。
  2. Silverlight 2 SDK を入れる。注意:Silverlight 2 Tools を入れようとするとエラーが出て失敗する。なので、Silverlight 2 Tools ではなく SDK を入れること、とあります。
  3. Silverlight 3 Beta SDK を入れる。注意:こちらも Silverlight 3 Tools ではダメ。Tools を入れること、とあります。
  4. Silverlight 3 Beta Developer Runtime を入れる。

だそうです。
どうやら、Tools ではなく SDK を入れてやる必要があるみたいですね。
こうしておくと、プロジェクトを新規作成したときに出るダイアログでバージョンを選択できるようになるようです。

記事の後半に

  • VS 2010 Beta 1 には 「Silverlight Navigation Application」 のテンプレートが無い。(VS 2008 + Silverlight 3 Beta Tools の場合はある)
    欲しけりゃ、テンプレートを VS 2008 でエクスポートして、VS 2010 でインポートしてくれ
  • .NET RIA Services を VS 2010 Beta 1 といっしょにインストールすることはできない

といった制限について書かれています。「まだベータの段階だってことを理解してほしい」 とも。


2009年5月20日水曜日

[Silverlight] カレンダーコントロールの祝日の背景色を変える

How to customize holiday appearance in the Silverlight Calendar [Jason Cooke]
Silverlight のカレンダーコントロールの祝日の背景色を変える方法が解説されています。
ただ、これはいろんな場合に応用できる方法ですので、カレンダーだとか祝日だとかはあんまり関係なかったりします。

まず、System.Windows.Data.IValueConverter を実装したコンバータを用意しておきます。
こいつは日付を受け取り、祝日だったらオレンジを、以外なら白を返します。
XAML 上では Resources でコンバータを取り込んでやって、あとはカレンダーコントロールのテンプレートを差し替えて背景色を決めるのにコンバータを使うようにしてやれば OK です。

同じ要領で何かを何かに変換するコンバータを作ってテンプレートを差し替えてやれば結構いろいろなことができそうですね。
むしろ、どのコントロールがどんなスタイル・テンプレートを持っているのかわかりにくい方が問題になるかも。
今回のカレンダーコントロールにしても 「カレンダーのそれぞれの日が CalendarDayButton になってて Grid で描かれてる」ってことを知ってれば 「じゃあその Grid の Background を変えればいいかな」 と発想できますが、そういったことを知らないとまずはそれらを調べるところから始めないといけませんからね。
今回のカレンダーコントロールのように Silverlight Toolkit に含まれているコントロールであれば、Toolkit のソース・XAML を眺めてみるってのもいいかもしれません。
けど、個人的には Silverlight Spy で中身を覗いちゃうのが一番わかりやすいような気がしてます。


[.NET] 4.0 の System.Lazy&lt;T&gt;

.Net Framework 4.0: Using System.Lazy<T>
ほう、System.Lazy<T> なんてものもあったのか。
サンプルのとおり、使用するときまで生成を遅らせる、ってものですね。

記事の最後に Lazy Computation in C# へのリンクがあります。
これはコミュニティコンテンツで C# MVP の方が書かれた Lazy<T> についての記事です。
しかし、2007年 12月かぁ。
ひょっとして、これを見て .NET Framework 4.0 に Lazy<T> が正式採用されたんだろうか?

まぁ、それはいいとして、この記事の大部分は Lazy<T> 自体の解説です。
見ればわかる通り、単にデリゲートを取っておいて初めて使うときにそいつを呼び出してやるというだけですね。
で、最後の方にサンプルがあります。
コンボボックスにフォント名とそのフォントで文字を描画したサンプルビットマップをデータバインドしてるんですが、このビットマップを Lazy<Bitmap> としています。
こうすれば、多数の使うかどうかわからないビットマップをあらかじめ作るってことをしなくて済むってわけですね。
まぁ、これくらいなら毎回描画しちゃった方がよっぽど速いだろという気もしないでもないですが(^^;


2009年5月19日火曜日

[VS] Visual Studio の T4 でコードジェネレーション

Visual Studio MAGAZINE: Visual Studio's T4 Code Generation
T4 (Text Transformation Templating Toolkit) というものについて解説されています。(まだ読んでないけど)
T4 は VS 2008 には標準で入ってるそうです。
VS 2005 の場合は DSL Toolkit を入れてやると入るみたいです。
で、こいつは ASP.NET みたいな感じのタグベースのコードジェネレータだそうです。

あと
Visual Studio 2010 Beta 1 shows lots of T4 usage + tangible T4 Editor for VS2010 Beta 1 is available!
によると、VS 2010 beta 1 でももちろん T4 は使われているそうです。
それとこの記事では tangible T4 Editor というものが紹介されています。
どうやらこれは T4 用のコードを書くときに使えるインテリセンスやハイライト表示、テンプレートギャラリなどをまとめたもの見たい。
Free 版(無料)と Pro 版(有料)があり。
この Tangible T4 Editor は、UML 形式のユースケース図、コンポーネント図、ステートチャート図、クラス図、アクティビティ図を書くような機能もあるみたいなんだけど、これはどういうことなんだろ?
T4 Editor に T4 を使ってこういった図を作るテンプレがついているってことなんだろうか?
このモデリング機能だけ別にしてもいいくらいのように思えるけど。
Free 版でも UML-Style Diagrams は書けるみたい。(けど、自動レイアウトとかビットマップにコピーとかができない)

ちなみに Tagible T4 Editor はすでに VS 2010 beta 1 に対応済みだそうです。
http://tangibleengineering.blogspot.com/2009/05/tangible-t4-editor-for-visual-studio.html
仕事速ぇ