« 2012年3月 | トップページ | 2012年6月 »

2012年4月

2012年4月30日 (月)

UCD Viewer 1.2.1リリース

Windows 7でパソコンが古いので、クラシックテーマを使ってたのですが、ちょっと、テーマを他のに変更したら見づらい・・

ということで、見た目を変更できるようにしました。

「View」->「Look & Feel」メニューからルック&フィールを変更できるようにしました。5つから選択できます。

Ucd1_2_1_0

Ucd1_2_1_1

Ucd1_2_1_2

とりあえず、3つだけ。この変更は終了時に保存されないので、毎回設定してください。

というかそれだけです。

2012年4月 9日 (月)

Windows 8 API List

Windows 7購入したので、Windows 8は購入しないけどdashdash

Windows 8に追加される予定のAPIを眺めててWindows Runtime以外の自分的に気になるものを・・。

まず、インターネット絡みだと、Web Sockets。

WinHttp でも、WinHttpWebSocketで始まる一連のAPIが追加されるようです。WinHttpは、後はWPAD(Web Proxy Auto-Discovery)絡みも拡張されて新たなAPIが追加されるっぽい。

後は、COMオブジェクトでネイティブから利用できるXML HTTP Request 2 略してXHR2?。

WinInetやWinHttpを直接扱うと、だるいんですdash(WinHttpにはCOMラッパーも用意されてるが)。XML HTTP Request 2というぐらいだから、その前のバージョンもあるんですが、大きな違いは、IXMLHTTPRequest2::SetCustomResponseStream 。これで、レスポンスを特定のストリームに受信できるようになるわけで、以前はこの仕組みがなかったので、巨大なファイルをダウンロードする時に、直接ファイルに保存とかできなかったのですが、これで解決happy02

インターネット以外だと、今更感があるが、Rich Edit 。OS付属のRich Editコントロールはずっとバージョンが4.1のままだったんだが、どうもRich Edit 8.0とパワーアップするっぽい。

TOM(Text Object Model) がバージョン2になって、ネイティブイメージサポートなど、画像の挿入やRichEdit Friendly Name Hyperlinks の扱いが楽に。

ちなみに、Twitter APIの変更などで動かなくなって、放置しているPiyotter は、タイムラインの描画にRich Editコントールの機能つかって描画してました。

Rich Editコントロールの各バージョンの機能については

これぐらいしかおもしろそうなのないdashdash

2012年4月 8日 (日)

Delphiで非同期プログラミング・・・おまけ

前回 簡単な固定スレッド数のスレッドプールを実装してみたが、自分で実装する事はバグの温床になりかねないわけで、最初はWindows Vistaで追加された新しいスレッドプールAPIを利用して実装しようとして、断念してましたが、せっかくなので。

まず、Vistaで追加された新しいスレッドプールAPIについては、

を参考に。

新しいスレッドプールAPIはプロセスに複数のスレッドプールを作成できたり、ペンディングの操作をキャンセルできたり、何より天下のマイクロソフト様が実装してるので、使わない手はないのですが、ちょっと、問題が・・・

Delphiでは、サブスレッドとGUIスレッドであるメインスレッドを簡単に同期するための仕組みとしてTThread.Synchronizeメソッドがあるわけですが、メインスレッド側で待機操作をする場合、定期的にClasses.pasのCheckSynchronize手続きを呼ばないと、サブスレッド側でTThread.Synchronizeされてた時に、デッドロックが発生しますが、Vistaで新しく追加されたスレッドプールAPIの、例えば、ワークコールバックが完了するまで待機するWaitForThreadpoolWorkCallbacks APIを見ると・・・

タイムアウトを指定できません。要するに定期的にCheckSynchronize手続きを呼べないわけで、あぼーんdashdash

TThread.SynchorizeはDelphi独自のメカニズムで同じような事を直接WinAPIのSendMessageでやっても、デッドロック(これからは、TThread.Queue(PostMessage)の時代?)。

単純に1対1にマッピングはできなくてある程度自分で作り込む必要あるっぽいねweep

まぁ、とりあえず、Vistaで追加された新しいスレッドプールAPIのヘッダだけでも


2012年4月 3日 (火)

Delphiで非同期プログラミング

Delphiがウンコ環境たる理由は標準で非同期操作がサポートされていないことです(他にも色々ないないだらけで、ウンザリなんですが・・)。JavaではFuture、.NETではIAsyncResultを使ったAPM (Asynchronous Programming Model)、EAP (Event-based asynchronous pattern)や最新の.NET 4ではTaskを使ったTask Parallel Library など非同期処理がお手軽にできるのですが、Delphiには標準でねぇ・・・・

ということで、勉強をかねて色々調べて簡単な実装をしてみました。最初は.NETのIAsyncResultをぱくろうとしましたが、GC(ガベージコレクタ)のない環境では実際に使ってみるとちょい無理あるということがわかったのでしょぼくれていたのですが、いいのを見つけました。Windows8でサポートされるというWinRTのIAsyncInfo(IAsyncAction,IAsyncOperation<TResult>)です(要するに.NETの簡易版Taskクラスじゃ?)。

実装したスレッドプールはワーカースレッド数が固定で変更はできません(最小・最大スレッド数を指定して、負荷に応じて実際のスレッド数をその範囲で増減なんて自分には実装できないので・・)。各メソッドの意味は実際にWinRTを試したわけじゃないですが、だいたい同じだと思うので、そのまんまMSDNのWinRTのWindows.Foundation namespaceWindows.System.Threading namespace の該当する説明を参考に・・

使い方は、TThreadPool.RunAsyncメソッドで非同期で実行する操作をパラメータとして渡します。RunAsyncメソッドを呼んだだけでは非同期操作が開始されません。開始するには戻り値のIAsyncAction.Startメソッドを呼びます。

非同期操作の終了を待ち合わせるにはIAsyncAction.GetResultsメソッドを呼びます。Startメソッドで開始された非同期操作は終了時に必ずIAsyncAction.Completedイベントが発生します(Cancelメソッドでキャンセルされた場合でも発生)。

実用的なアプリは通常、任意の数の非同期操作を行うと思いますが、上記だけじゃ役不足で、そのための仕組みがThreading.AsyncUtils.pasに定義されている、TAsyncGroupクラスです。

非同期操作をグループとして管理するクラスです。TThreadクラスを直接派生させる場合も同じですが、基本、GCのない環境では非同期操作の終了待ち合わせをしないと死にます。例えば、非同期操作の内部で、TThread.Synchronizeメソッドなどで、フォームのメンバにアクセスする場合、非同期操作が完了する前にフォームが閉じられたりすると、アクセスバイオレーションが発生します。TAsyncGroupクラスはグループとして管理するクラスというわりには、何もしない優れものクラスgawkでAddメソッド、Removeメソッドで自前で追加・削除してください・・dashdashShutdownメソッドでグループをシャットダウンします。シャットダウンした後は追加できません。WaitForTerminationで空になるまで待機します。要するにこれで終了待ち合わせを行います。

IAsyncInfo.Startメソッドで開始する前に必ずTAsyncGroup.Addで追加、IAsyncInfo.Completedイベント内などで必ずTAsyncGroup.Removeで削除をペアで・・

グルーピングする粒度は作るアプリの種類や作り方によりけりですが、とりあえず、フォームごとにAsyncGroupを用意すれば十分だと・・例えば、こんな感じで。

デモアプリは現状ありませんが、とりあえず、作りかけで放置している、Tumblrビューワに組み込んだところ、えらい速くなったような気がぁ・・

Async1

組み込む前は1画像毎にダウンロード用のスレッドを生成してたので、そりゃものすごい回数のスレッドの生成・破棄が発生していた・・固定スレッドのプールといえど、ないよりはずっとましgood

まぁ、実際のアプリで使う場合は他の人が作った高機能なOmniThreadLibraryAsyncCalls とか使った方がいいと思うが、いちいちクレジットの表記とかライセンス絡みがだるすぎ・・・

というか、Delphiが最低限こんな感じの仕組みなりを標準で用意してくれりゃ、前に作ったDelphi用のWindows Liveライブラリ に、非同期バージョンのメソッドILiveClient.EnumerateResourcesAsync(...): IAsyncOperation<IEnumerable<IResource>>とか追加してみたいんだが・・

ダウンロードはSkyDriveから

Delphi 2010以降が必要です。

« 2012年3月 | トップページ | 2012年6月 »

自作ソフトウェア

無料ブログはココログ

メモ