.NET 開発テクノロジー入門

Microsoft MVP [先着20名プレゼント]「.NET 開発テクノロジー入門(Visual Studio 2010対応版)」出版しました!


MVP Weekly Newsletter 2010 年 12 月 15 日号


ということなので、応募したら早速送られてきたから読んでみました。で、感想です。


.NET開発テクノロジー入門 VISUAL STUDIO 2010対応版 (MSDNプログラミングシリーズ)

.NET開発テクノロジー入門 VISUAL STUDIO 2010対応版 (MSDNプログラミングシリーズ)


.NET 開発の概要を知るには格好の良書

といった Microsoft の最新開発テクノロジーの概要を体系的に解説しています。各テクノロジーごとに著者が違うため、章ごとの読みやすさが変わりますが、MS の最新開発テクノロジーを体系的に抑えるには格好の良書といった感があります。
ASP.NETASP.NET MVC はどう違うのか。WPFSilverlight、シーンによってどちらを採用すべきか。WCF や 並列プログラミングって何なの? これらの答えは本書を読めば自ずと明らかになるでしょう。また全体を通し読んでみておぼろげながら浮かんでくるのが Microsoft が目指す方向です。それに応じて我々エンジニアが将来求められる姿は何なのか、いろいろ考えさせられるものがありました。
各章の概説に関しては id:waritohutsu さんがブログで判りやすく解説してますので、そちらを参考にするといいかと思います。

参考記事:「.NET開発テクノロジー入門 Visual Studio 2010対応版」の書評なんぞをしてみる

WindwosForms は.NET 2.0 でおしまい?

WPF の項を読んでて気になったのが WindowsForms の今後。以下本書からの抜粋ですが、この表を見るだけでも Microsoft は今後明らかに WindwosForms を切り捨て WPF に移行するものと考えられます。

Windows クライアントアプリケーションのプレゼンテーション技術は、Win32、MFCVisual Basic、さらに .NET Framework の Windows Forms と発展し、現在の .NET Framework(バージョン4) では Windows Presentation Foundation(WPF) がその役を担っています。

プレゼンテーション要素 Win32 MFC Visual Basic Windows Froms WPF
APIフレームワーク Win32 C++ Visual Basic .NET Framwork 2.0まで .NET Framework 3.0以降


.NET 開発テクノロジー入門 P97


Windows Froms が 「.NET Framwork 2.0まで」 になってるし!ここだけ読んでも判るとおり、将来のバージョンで Windows Forms に新しいコントロールが加わったり、既存のクラスを改修し新規メソッドが増えることはないのでしょう。それよりもむしろ WPF を採用して欲しいというのが Microsoft の考えであり、Windows 7 以降のアプリケーション開発の主流になると思います。
でもやっと WindowsForms に慣れたばかりのプログラマが、ただちに WPF に移行できるかというとそう簡単にはいかんでしょう。自分で作業してても感じますが WinForm と WPF ではベースとなるアーキテクチャが違いすぎるので、そう易々移行できるとは思えません。いまの WinForm エンジニア達が WPF に移行するには後2〜3年・・・いや下手すりゃ5〜10年かかるのでは?と思いますね。もっともその頃にはまた新しい技術が出てるんでしょうがw


並列プログラミング

読んでて面白いというか、やっと判った感があるのがこの並列プログラミング。もっと複雑な知識やコーディングが必要なのかと思ったらそうではなく、わずかなクラスやメソッドで並列処理が実行されるようフレームワーク側で機能を提供しています。本書では

  • 並列プログラミングの基礎知識
  • タスク並列ライブラリ(Task)
  • タスク並列ライブラリ(Parallel)
  • PLINQ
  • 同時実行コレクション
  • VS2010 の並列機能デバッガーとプロファイラー

の順で .NET Framework 4 の並列プログラミングを判りやすく解説してくれてます。


タスク並列ライブラリ(Parallel)

参考&予習を兼ねて本書内のコードを挙げて少し紹介させていただきたいと思います。本書ではすべて C# でコーディングされているますが、そのままコピペも何なので VB.NET で書いてみました。私、普段の作業の比重は VB 寄りなので、VBユーザーにはとっても優しいんですw


まず、逐次実行のコードです。スレッドID はすべて 1、実行時間は私の環境で平均 2500 ミリ秒かかります。

Option Explicit On
Option Strict On

Imports System.Threading
Imports System.IO


Class Program

    Shared arr As String() =
        Directory.GetFiles("C:\Users\Public\Pictures\Sample Pictures", "*.jpg")

    Shared Sub Main()

        Dim sw = Stopwatch.StartNew()
        DoIt()
        Console.WriteLine("Elapsed = " + sw.ElapsedMilliseconds.ToString())
        Console.ReadLine()

    End Sub

    Private Shared Sub DoIt()

        For Each ip As String In arr
            Program.SimulateProcessing()
            Console.WriteLine(ip + TID)
        Next

        Console.WriteLine("Done")

    End Sub

    Private Shared Sub SimulateProcessing()
        Thread.SpinWait(100000000)
    End Sub

    Private Shared ReadOnly Property TID() As String
        Get
            Return "TID = " + Thread.CurrentThread.ManagedThreadId.ToString()
        End Get
    End Property

End Class


次は For Each ステートメントを Parallel.Foreach に変更したコードです。System.Threading.Tasks を Import し、DoIt メソッド内のコードを変更します。

Option Explicit On
Option Strict On

Imports System.Threading
Imports System.Threading.Tasks
Imports System.IO


Class Program

    Shared arr As String() =
        Directory.GetFiles("C:\Users\Public\Pictures\Sample Pictures", "*.jpg")

    Shared Sub Main()

        Dim sw = Stopwatch.StartNew()
        DoIt()
        Console.WriteLine("Elapsed = " + sw.ElapsedMilliseconds.ToString())
        Console.ReadLine()

    End Sub

    Private Shared Sub DoIt()

        Parallel.ForEach(
            arr,
            Sub(ip)
                Program.SimulateProcessing()
                Console.WriteLine(ip + TID)
            End Sub)

        Console.WriteLine("Done")

    End Sub

    Private Shared Sub SimulateProcessing()
        Thread.SpinWait(100000000)
    End Sub

    Private Shared ReadOnly Property TID() As String
        Get
            Return "TID = " + Thread.CurrentThread.ManagedThreadId.ToString()
        End Get
    End Property

End Class


前回は2秒以上かかったコードが、1500ミリ秒前後に短縮しました。さらにスレッドID が 1・3・4 と三つのスレッドで実行されているのが確認できました。(なぜか 2 がない・・・)


PLINQ

お次は PLINQ 。例えば以下のコード。

Option Explicit On
Option Strict On

Imports System.Threading
Imports System.Collections


Module Module1

    Sub Main()

        Dim sw = Stopwatch.StartNew()

        DoIt()

        Console.WriteLine("Elapsed = " + sw.ElapsedMilliseconds.ToString())
        Console.ReadLine()

    End Sub

    Private Sub DoIt()

        Dim arr As IEnumerable(Of Integer) = Enumerable.Range(2, 400000)
        Dim list = (From n In arr.AsParallel()
                Where IsPrime(n)
                Select n).ToList()
        Console.WriteLine(list.Count.Tostring())

    End Sub

    Private Function IsPrime(ByVal p As Integer) As Boolean

        Dim upperBound As Integer = CInt(Math.Sqrt(p))
        For i As Integer = 2 To upperBound
            If (p Mod i) = 0 Then Return False
        Next
        Return True

    End Function

End Module


このコードで使われている並列プログラミングのテクニックは、DoIt メソッド内で使われています。

Private Sub DoIt()

    Dim arr As IEnumerable(Of Integer) = Enumerable.Range(2, 400000)
    Dim list = (From n In arr.AsParallel()
                Where IsPrime(n)
                Select n).ToList()
    Console.WriteLine(list.Count.Tostring())

End Sub


メソッド内の LINQ 部分、「.AsParallel()」 の箇所だけです。これがなければただの LINQ を使ったコードですが、.AsParallel() という拡張メソッドを付けた途端、CPU のコア数に応じてスレッドを立ち上げ並列に動作します。私の環境、AMD Phenom 9550 では AsParallel のない通常の LINQ コードだと平均600ミリ秒、しかし AsParallel メソッドを使った場合だと平均 300ミリ秒と二倍近く速くなりました。これが .NET4 以降追加された PLINQ という LINQ の並列化テクニックだそうです。


並列プログラミングというのは何かとっつきにくい感があって MSDN を見てもイマイチよく判りにくい部分があったのですが、サンプルを通して初めてその威力を実感できると同時に、比較的簡単なコーディングでその恩恵を享受できることが本書を通して判りました。私にとってはこれだけでも大変な収穫です。