カテゴリー別アーカイブ: Windows Azure

Azure WebSites の .NET Framework が 4.5.1 にアップデートされました。

Azure WebSites の .NET Framework が、4.5 から 4.5.1 にインプレースアップデートされたみたいですね。うちのテナントのインスタンスも確かめなくちゃ。ちなみに、この情報は、しばやん大先生のブログ記事を見つけてくれた、うちの会社の若い子によります。ありがとう。若い子!

何が重要かって、TransactionScope の async/await インフラストラクチャ対応ですよ。Entity Framework 6 の DbContext が非同期実行に対応しているのに対し、TransactionScope は対応していなかったんです。

具体的には、await される度にどのスレッドで再開されるかわからないのが async/await です(実際は、WPFだとUIスレッドに戻ってきたり、ASP.NETだとどのスレッドかわからないけど HttpContext は同一だったりし、フレームワークに合ったコンテキストの保ち方をします)。しかし、EF5 までの DbContext も、.NET 4.5 までの TransactionScope もスレッド依存だったんですね。TransactionScope に関しては、ライフサイクルをスレッドで管理していたようで(おそらく)、await に対応するには、SyncrhonizationContext で管理する必要があると考えられます。おそらく 4.5.1 からそれに対応できたのでしょう。TransctionScope コンストラクタのパラメータに、非同期対応を行うか同課のパラメータが追加されました。ちなみに、.NET 4.5.1 は、Windows Server 2012 R2 にはインストールされているので、ずいぶん前にリリースされています。

しかし、ちょーお手軽 PaaS (IIS の間貸し)である Azure WebSites は、ベースOSがWindows Server 2012 のまま。.NET Framework だけアップデートしようにも、IaaS ではないので、対応を待つしかありませんでした。そして、いつの間にか更新されていました。

TransactionScope が async/await に非対応なら、それ相当の書き方があるのでいいっちゃいいんですが、ようは、トランザクション区間に入って出るまでを1スレッドで実行しなくちゃいけないので、せっかくの async/await インフラストラクチャもタスクパケットの占有時間が長いわけです。CPU時間がもったいないことになるのです。

さて、これで心おきなく Entity Framework と TransactionScope で async/await できるぞ!

広告

Windows Azure上にネイティブコードを含むWebアプリケーションを配備する

マイクロソフト社のプラットフォーム「Windows Azure」に、ネイティブコードを含むアプリケーションを配備するための、抑えておくべきコト。今回は「WebSites」もしくは「クラウドサービス」の「Webロール」から、ネイティブコードであるDLLをP/Invokeするための環境を構築する上で抑えておくべきポイントを挙げます。記事の執筆時では、IDEはVisual Studio 2013 RCです。

1.IISでネイティブコードを走らせる

IISにおけるネイティブコードには種類があります。「Fast CGI」「HTTPハンドラ」「P/Invoke」といった、ネイティブコードを走らせるにも選択肢があります。当記事では、「P/Invoke」について述べます。

 

P/Invokeは、マネージドコードをターゲットに開発されたアプリケーションから、既存資産の利用、速度向上、プラットフォームのAPIの利用などの目的で、手軽にネイティブコードがコールできる.NET側に実装されているインターフェイスです。Win32 API群をはじめとする、既存の(そして古くから存在する)DLLに改修を行うことなく、マネージドコードから関数を利用できるため、資産活用の観点でとても有用です。また、特殊な計算や機能を持ったライブラリがネイティブコードで書かれているケースは多く、それらを手軽に利用しようとしたときにもP/Invokeは有用な相互運用手段です。

 

IIS上に配備するマネージドコードで構成されたWebアプリケーションも、もちろんP/Invokeを使用することができます。ただし、IISのセキュリティモデルの影響は受けるため、Webアプリケーションでネイティブコードの実行を許可させるためには多少設定等必要となります。

2.Azure上に配備するためには

Azure上でネイティブコードを実行するには、いくつかの制約があり、それに準じたDLLの作成や、Azure上のインスタンスの設定が必要となります。

(1)カスタムのDLLのビルドのターゲットは64ビットかつReleaseビルドでなければならない。

(2)上記DLLから参照される他のDLLも64ビットでなければならない。

※2013年12月28日追記:この修正記事執筆時においては、Azure WebSitesのOSはWindows Server 2012だと考えられます。2012 R2ではなさそうです。この環境において、ネイティブアプリケーションを Visual Studio 2013 で開発し、ランタイムライブラリ MSVCR120.DLL を配備する必要がある場合は注意が必要です。P/Invoke によるDLLの遅延ロード時にBadImageFormatExeptionが発生します。後述するプラットフォームの選択において64ビットを選択しても発生します。VC++のランタイムが2012 R2より前のプラットフォームに対応していないと思われます。この場合は、ネイティブアプリケーションにランタイムを静的リンクしてください(コンパイルオプション /MT)。いずれベースOSがServer 2012 R2になったり、VS2013のサービスパックが出た時点で解消されることを願って…。

(3)参照される他のDLLのうち、Azure上のOSイメージに含まれていないDLLは、カスタムDLL同様、Webアプリケーションと共に配備しなければならない。

(4)WebアプリケーションのWeb.configに、「完全信頼」のセキュリティポリシを記述する。※2013/12/28追記:<trustLevel>で、各信頼レベルごとの設定ファイルを指定し、<trust>で、どの信頼レベルで稼働させるかを選択します。

<system.web>
  <securityPolicy>
    <trustLevel name=”Full” policyFile=”internal” />
  </securityPolicy>
<trust level=”Full” originUrl=”” processRequestInApplicationTrust=”true” />

</system.web>

なお、「信頼レベル」が「Full」というのは、「無制限のアクセス」ということです。逆に「Minimal」というのは、「最小レベルのアクセス」しか許可されない、最も制約の多い信頼レベルです。ネイティブコードを動かすには、無制限のアクセスが必要ということです。文言とセキュリティレベルの高さは逆なので注意が必用です。

そして、この信頼レベルの設定は、提供されているIISの規定値から制約を強めるための仕組みのようです。つまり、ホスティングサービスが既定でどの信頼レベルで稼働しているかが、アプリケーションの制約に影響します。Azure WebSites は既定で「Full」で稼働しているようです。従って、上記設定をWeb.configに記述しなくてもネイティブコードは動きます。ただ、Azure WebSitesが既定「Full」で提供され続けるかどうかは分かりませんが、変更されるとなればアプリケーションに大きな影響があるため、アナウンスはされると思いますが…。

(5)Azureにおいて、「クラウドサービス」のWebロール・ワーカーロールは64ビット環境なので配備可能。

(6)WebSitesは、モードが「標準」(環境がサブスクリプションで占有可能なモード)であり、かつ、プラットフォームを64ビットで選択した場合のみ配備可能。概念的にはWindows Serverインスタンス1つを64ビット環境で占有しないとダメってことね。

快適なNative on Azure lifeを!

2013-11-07 追記:

MSDNにより詳しい内容が掲載されました。

http://msdn.microsoft.com/ja-jp/library/windowsazure/hh694038.aspx