プロが教えるわが家の防犯対策術!

ASP.NET + C#でシステムを開発しているのですが、別システムから提供されている
スレッドセーフでないAPIを利用しなければならなくなりました。
(このAPI自体は別のシステム会社が提供しており、改修することができません。)

APIは別システムへのログイン、各種情報取得、ログアウトを提供していますが、
セッション管理部分が共有(staticになっている?)されているらしく、あるスレッドが
ログインした直後に別スレッドがログアウトすると、先のスレッドでの情報取得が
セッション切れでエラーになってしまいます。

このような場合、どのような解決方法が一般的でしょうか?
具体的にご教示いただけると幸いです。

A 回答 (3件)

こういう状況で使うオブジェクトは


ミューテックスなんですが、スレッド間で
共有しなければならないので難しい
制御になります。クリティカルパスは
もっと面倒です。

そこで、一番安直なのが、ファイルを使う
方法です。
サーバ内のあるファイルを排他的に開き
ます。開けたスレッドはそのAPIを使い
ます。使い終わったらファイルを閉じます。
開けない(他のスレッドが処理中)場合は
Sleepを入れて、何回かリトライします。
ファイルはミューテックス代わりに使うので、
内容は意味がありません。(0バイトでよい)
Sleepの時間、リトライの回数は状況により
変えられるようにしておいて、最適値を
カットアンドトライで決めます。

但し、このAPIの処理時間がかなり掛かる
場合は上記のような制御ですと、処理が
集中した時にタイムアウトになるかも知れ
ません。
別の解決としてはこのAPIで情報を収集
する独立したEXEを作り、プロセスの起動で
情報を集めることを考えます。プロセス内は
シングルスレッドで、プロセス空間が異なる
ので、干渉する心配はありません。
データの受渡ですが、EXEは標準入出力を
使い、呼び出し側はパイプを作って、起動
するプロセスの標準入出力にアサインします。
これでファイル(後始末がいる)を使わず、他の
プロセスとも干渉しない方法でデータを受渡
できるようになります。
パイプはプロセス間継承が可能なようにし、
2セット(パイプは入出力ペアなので、1セット
あたり2ハンドルできる)作ります。
つまり、標準入力、標準出力、エラー出力です。
アサイン時に入力用パイプを標準出力やエラー
出力にアサインし、出力用パイプを標準入力に
することです。間違いやすいので注意しましょう。
尚、タイマなどで制御しないでパイプを読み込みに
行くと、書き込み側がフラッシュするまでブロック
されますので、必ずタイマ付きか、プロセスの
終了を待って読みにいってください。

後者は難しいのですが、APIの処理時間が
長い場合は採用した方がよいでしょう。
後始末のいらないインターフェースとしては
ウィンドウがあり、こちらは継承しないでも利用
できますし、イベントで処理がきるので、楽ですが、
Webコンテナのサービスのデスクトップとの対話を
可能にしておかないと、受け渡しできません。

物理ファイルで受け渡すのはファイル名の問題、
使用後の削除の問題が残るので、個人的には
薦められません。
    • good
    • 0

完全に行うのは、無理な相談なのですが、



複数のスレッドから同時に呼び出される可能性があるプログラムは、「再入可能プログラム」という作り方をしなければなりません。これは、プログラムが呼び出されるたびに、すべての変数領域、ワークファイルなどの入出力管理を新たに設定し、呼び出しプログラムごとに別の動作をし、別の価を返すことができるようになっていないといけません。
質問文にあるように、STATIC変数などを使用してはいけないわけです。

で、再入可能でないプログラムを複数のプログラムから呼び出したいとなると、「再入させない」しか、方法はありません。1つのプログラムが呼び出している間は、フラグを立てて、別のプログラムはそれが終わるまで待っているようにします。

フラグを立てる方法としては、No.1回答のようにファイルを作るというのもひとつの方法です。状況に合わせて、最適な方法を考えてください。
    • good
    • 0

ASPもC#も触ったことのない私が言うのもなんですが、


>このような場合、どのような解決方法が一般的でしょうか?

もとAPIに触れないなら

ログイン状況をトランズアクションごとに取得して、必要なら再度ログインさせる。
「有るスレッドがログインした直後」にログアウト処理を行う必要性が出た場合はある程度待たせてからログアウト処理を行う。

以外には思いつきませんが、、、
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!