色々実験をしていてついに実現させました。
主にfoomciの機能改善に役立てるほか、他の連携アプリケーションとの強力な相互連携が可能になるものと思われます。
現在のバージョンのfoomciはWSH Panel Modからfoomciへの一方的な連携しかできていませんでした。
故に現在再生中の時刻(position)などの情報をfoomciからWSH Panelは知るすべがなく、
シークバーはクリックすればシークはするが、現在再生中のポジションが分からないという事態に陥っていました。
1.Foomciの大まかな仕組みと、一方通行からの脱却
上がおおまかなfoomciの仕組みの説明です。
まあ、シーク機能を実現させるために結構苦労したんだなあと、
後なんて馬鹿で無駄なことしてんだ俺とも思っています(^_^;)
まさに黒歴史
上の図を見てわかるように、WSHからfoomciには矢印は伸びていますが、foomciからWSHには伸びていないことがわかります。
まさに苦肉の策でやっていたことがわかります。
今回、実験的なアプリケーションで実装したのは、WSHからアプリ、アプリからWSHへと相互連携を実現する機能です。
早い話が、今まで散々してきたstdIn/Out/(Err)の活用でした。
最初の構想では、単純にフォームアプリケーションでConsole.Write/Read(Line)で簡単に実装できると思っていたのですが中々うまく行かなかったのです。
2.フォームが固まって動かない!?
適当にフォームのロードが終わったあたりでConsole.Read/Writeをループさせていればいいやと思っていたのですが、
いざ実装して動かしてみると、単独ではなんの問題もないのですが、WSHから標準入出力をリダイレクトされた状態で起動するとフォームが固まって動かなくなるのです。
原因は日曜プログラマには容易にはわかりませんでした。
で結局色々試したところ、どうやら、そのConsole.Read/Writeのループが原因らしいという結論に行き着いたのです。
ウインドウフォームアプリケーションは手続き型プログラミングで動いています。
つまり、フォームのロードが完了した部分でループをさせてしまうと、
フォームのロードが完了した時点で呼び出されるイベントがいつまでたっても終わることが無いので、固まってしまうのだろうという結論です。
ではタイマーを作ってタイマーイベントごとにConsole.Read/Writeを実行させれば・・・
コレもどうやらダメでした。フォームは固まらないのですが、WSH・フォームアプリケーション両者とも全く無反応になってしまいました。
ああ、コレはもうだめかな?そう思ってしまったりもしました。
3.救世主はよく聞くことは聞くアレ
「・・・まるちすれっど???」
マルチスレッドがどうこうは知識として有りました。平行して何かを処理する際に、処理効率が上がるという噂のアレ。
でも自分が作るツールでは、そんな知識としてはあっても、使うことのない関係ないものと思っていましたが、今回の救世主はまさにコレでした。
翌々考えてみれば当たり前の発想ですね、フォームアプリケーションではフォームで発生したイベントを処理させるスレッドと、
Console.Read/Writeをループさせるスレッドを独立させてやればいいのだ、しかし、そんなことが本当にできるのか?
少し疑問でしたがやけくそでやって見ました。
結果はうぉぉおおおおおおぉおおおおおおおおおおおおおおおおお動いたぜぇえええぇぇええええええええええ!!!!!!!!!!!!!!!!
職業プログラマさんにとっては「何言ってんだこいつ」てなるでしょうが、学部生日曜プログラマにとっては、初めてのことで実に新鮮でした。
なるほど、マルチスレッドとはこういう場面でも使えるのだな、とまた一つ学習しました(元々の頭が空っぽなのでどんどん入っていく)。
しばらくやっているうちに、少し困った問題が、フォームを閉じてもプロセスが死なないのです。
しかし、それも解析機関Gがすぐに解決してくれました。
thread.IsBackgroundを真にすればいいのですね。
でWSH側と色々いじっていた結果、やりたいことが実現できました!
将来像はこんな感じです
これで外部アプリケーションとfoobar等、2つ以上のプロセスの完全な相互連携を実現できるようになります。
なおこれは何もfoobarのWSH Panel Modだけでなく、その他様々な方面でも活用できそうな技術です。
またまた、表現の幅が広がったというものですね、尚これはまだ実験的なものだったので、
今後はアプリケーションの安全性や安定性についても検討が必要なようですが大きな壁はひとつ確実に超えたみたいです。
0 件のコメント:
コメントを投稿