現在の仕事で、C# でコーディングされたレガシー ライブラリを維持する特権を「獲得」しました。
この dll:
- COM オブジェクトを呼び出すしかない、Uniface で作成された大規模なレガシー システムのメソッドを公開します。
- このレガシー システムと別のシステムの API との間のリンクとして機能します。
- 場合によっては UI に WinForm を使用します。
コンポーネントを理解しているので、より視覚的に:
*[Big legacy system in Uniface]*
==[COM]==> [C# Library]
==[マネージ API]==> *[Big EDM Management System]*
問題は、この C# ライブラリのメソッドの 1 つが実行に時間がかかりすぎるため、非同期にする必要があるということです。
私は C# には慣れていますが、COM にはまったく慣れていません。私はすでに並行プログラミングを行っていますが、COM はそれに多くの複雑さを追加しているようで、これまでのすべての試行は次のいずれかで終了します。
- エラー メッセージがまったく表示されないクラッシュ
- 私のDllは部分的にしか機能せず(UIの一部のみを表示してから閉じます)、それでもエラーはまったく発生しません
COM dll 内でスレッドを処理する方法についてのアイデアやリソースが不足しています。ヒントやヘルプをいただければ幸いです。
これまでのところ、メソッドを非同期にするために変更したコードの最大の部分は次のとおりです。
// my public method called by the external system
public int ComparedSearch(string application, out string errMsg) {
errMsg = "";
try {
Action<string> asyncOp = AsyncComparedSearch;
asyncOp.BeginInvoke(application, null, null);
} catch (ex) {
// ...
}
return 0;
}
private int AsyncComparedSearch(string application) {
// my actual method doing the work, that was the called method before
}
ヒントや有用なリソースをいただければ幸いです。ありがとうございました。
更新 1:
以下の回答と手がかりに従って (特に について、この例SynchronizationContext
の助けを借りて)、コードをリファクタリングして機能させることができましたが、それは COM ではなく C# の別の Window アプリケーションから呼び出された場合のみでした。関数を呼び出すと、従来のシステムで非常にあいまいなエラーが発生し、クラッシュに関する詳細が表示されません。
更新 2:
私の試行における最新の更新: Uniface システムからではなく、テスト プロジェクトから呼び出しが行われたときに、マルチスレッドを機能させることができました。複数の試行の後、レガシー システムは現在の構成ではマルチスレッドを十分にサポートしていないと考える傾向があります。しかし、それはもはや問題のポイントではありません:)
動作しているように見えるコードの抜粋を次に示します。
string application;
SynchronizationContext context;
// my public method called by the external system
public int ComparedSearch(string application, out string errMsg) {
this.application = application;
context = WindowsFormsSynchronizationContext.Current;
Thread t = new Thread(new ThreadStart(AsyncComparedSearchAndShowDocs));
t.Start();
errMsg = "";
return 0;
}
private void AsyncComparedSearch() {
// ANY WORK THAT AS NOTHING TO DO WITH UI
context.Send(new SendOrPostCallback(
delegate(object state)
{
// METHODS THAT MANAGE UI SOMEHOW
}
), null);
}
現在、このライブラリを Windows サービスにカプセル化し、システムとサービス間のインターフェイスを作成するなど、この COM アセンブリを変更する以外の解決策を検討しています。もっとサステイナブルになればいいのに..