アンマネージ コードからの SIGABRT を処理できますが、少し面倒です。完全に C# で実行できる可能性もありますが、私の方法では、それを機能させるために C++/CLI アセンブリが必要です (少なくともすべてが 1 つのプロセスで行われます)。
ステップ 1: C++/CLI クラス ライブラリ プロジェクトを作成し、*.h ファイルに次の関数を配置します。
namespace ClassLibrary1 {
public ref class Class1
{
public:
static void callaborter();
};
}
ステップ 2: cpp ファイルに次のコードを追加します。
// This is the main DLL file.
#include "stdafx.h"
#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <iostream>
#include "ClassLibrary1.h"
#include "..\Win32Project1\Win32Project1.h"
#pragma managed(push, off)
jmp_buf env;
void on_sigabrt (int signum)
{
longjmp (env, 1);
}
void run()
{
if (setjmp (env) == 0) {
signal(SIGABRT, &on_sigabrt);
fnWin32Project1();
}
else {
std::cout << "aborted\n";
}
}
#pragma managed(pop)
void ClassLibrary1::Class1::callaborter()
{
run();
}
クラスライブラリとクラスの名前はデフォルトのままにしました。中止関数は call fnWinProject1() です。問題のある DLL をこのプロジェクトに直接リンクする必要があります (C++ の場合と同様)。
C# クラスに C++/CLI アセンブリへの参照を含め、「callaborter」メソッドを呼び出します。
実行中のコードは、SIGABRT (abort() によって呼び出される) のキャッチャーをセットアップし、on_sigabrt() でそれを処理します。これにより、関数全体が停止します。その後、クリーンアップして再試行できます。
OPが便利な名前を選択するための演習として残します。
注: デバッグでは、中止ダイアログが引き続き表示されます。続行するには、[無視] を押してください。リリースでは、ダイアログは表示されません。
PS私は、このstackoverflowの質問に基づいて応答を作成したことに言及する必要があります: SIGABRTシグナルを処理する方法は?