質問: タイトルの通りの現象に困っています サーバーは Windows Server 2012 R2 開発環境はVisual Studio 2015 + ASP.NET (.NET Framework 4.6.2) です ざっくり現象を書くと Unmanaged dllを使ったWeb APIを呼ぶと固まってしまう 同様の処理をCのCGI(exe)で実行するとちゃんと動く です いろいろ試した結果を含めて詳細を以下に書きます --- 1. サードパーティ製ライブラリを2種類使用するUnmanaged dll(64bit)を作成しています(このDLLを1とします) 2. C言語のコンソールアプリで1をリンクして関数を呼ぶものを作りました(2) MVCのWeb Api 2コントローラーを作成して1を呼ぶものを作りました(3) 3. 2,3はサーバーに配置してどちらもIISを通して呼ぶようにしました 4. サーバーを再起動してサービスが立ち上がったと思われるタイミングで2を呼ぶと常識的な時間で応答を返してくれました 5. 同じことを3で試すと応答がかえって来ません(クライアント側のタイムアウトや、アプリケーションプールのPingエラーで強制終了させられる) この状態は30分ほど待っても改善しません(それ以上は待っていないのでわかりません) 6. 2を呼んだあと3を呼ぶと1,2回くらいの試行で応答を返してくれます 7. 一度でも応答を返すとあとは普通に応答を返します iisresetコマンド等で再起動しても返します 8. サーバーを再起動すると元(応答を返さない状態)に戻ります 9. 「起動が遅い」等で調べると``が出てきたので試してみましたが変わりませんでした(v4以降は関係ないという記述もありましたし、今はサーバーをインターネットにつないでいる状態ですが変化なしです) 10. 1の各ステップでログを出力するようにしたところ、サードパーティ製ライブラリの初期化周辺で止まっているようなのですが、止まる箇所は固定ではありませんでした(ログは毎回flushして閉じているので多分止まる直前を示していると思います) --- という感じでして途方に暮れています 原因や回避策があれば教えていただけますでしょうか
回答: DLL を リンクしてメソッド呼び出しの場合と、 exe 外部プロセスとして呼んだ場合の違いとして 1)マルチスレッドの問題 2)リソースの開放漏れの問題 の違いがあると思います。 exe 起動の場合、呼び出し終了時に メモリー上にあるリソースはすべて開放されます。 dll から呼び出した場合に 関数内で 重要なリソースを開放していない場合には問題となります。 > > 5. サービスが立ち上がったと思われるタイミングで3 を呼ぶと応答が返ってきません。 > 6. 2を呼んだあと3を呼ぶと1,2回くらいの試行で応答を返してくれます > 7. 一度でも応答を返すとあとは普通に応答を返します > > > この部分を考慮すると、DLL 呼び出しの初期化ルーチンを処理中に 次の 3 呼び出しが発生してデッドロックが発生しているのでは? と感じました。 3 を呼び出す時に `System.Threading.Mutex` を使って 処理を マルチスレッドで 行わないように排他処理を入れてみたらどうでしょうか? > > 7. 一度でも応答を返すとあとは普通に応答を返します > > > 2回目以降は マルチスレッドでちゃんと動作するようなら `Mutex` による排他は 初回だけでもいいのかもしれません。 しかし、そもそも ライブラリが マルチスレッドに対応していないのなら 呼び出し毎に 排他する必要があります。 あとは、長時間利用して 該当のネイティブアプリが メモリーリーク等が 発生していないか? 長期的に確認する必要があると思います。