いを抑えます。abort()エラー C#?
-
11-09-2019 - |
質問
感を示すスプラッシュ画面の背景にスレッドがプログラム。一度荷重感染のスレッドとしても目的にしたものをまぶす。
私の問題は中止スレッドで投げ ThreadAbortException
ユーザーでは、続行をクリックします。
う扱うか。っている気がします。を抑制するような-->
try
{
Program.splashThread.Abort();
}
catch(Exception ex)
{
}
って感じですが、それによく怒ら、うまくいきませんでします。
よろしく!
解決
あなたはスレッドをキャンセルする必要はありません。私はコードで例示します。
スプラッシュ画面形式で
public void CloseSplash()
{
Invoke((MethodInvoker)delegate
{
this.Close();
});
}
のProgram.csファイルでます:
private static Splash _splash = null;
public static void CloseSplash()
{
if (_splash!= null)
{
_splash.CloseSplash();
}
}
さて、あなたのMainメソッドの開始時に、スレッドでスプラッシュを表示します:
Thread t = new Thread(new ThreadStart(delegate
{
_splash = new Splash();
_splash.ShowDialog();
}));
t.Start();
...そしてあなたはそれを閉じたいとき、ちょうどそれを閉じます:
Program.CloseSplash();
次に、あなたがスレッドを中止心配する必要はありません。それが正常に終了します。
他のヒント
下記をご参照くださいリンクの取得を行うにはGoogle検索の最初の成果は、返される):
http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx
特別な注意を払うこそ
このメソッドが呼び出されるスレッドは、システム投げ ThreadAbortException のスレッドを中断します。 ThreadAbortException 特別な例外の場合、できることが制限されてアプリケーションコードが再スローされるのがcatchブロックを除 ResetAbort が呼び出されます。 ResetAbort 解除の請求"stop"ボタンをクリックを防ぐ ThreadAbortException から終了ます。寄最終的に、ブロックは実行される前にスレッドが中断されました。
Threadabortを使用することはrecommenedされていません。それは悪です。なぜ(オート/マニュアル)ResetEventのような別のメカニズムを使用していませんか? スプラッシュ・スクリーンを持つスレッドを起動し、イベントを待ちます。他のコードは、ものをロードして行われている場合は、イベント専用のスプラッシュ画面自体がノーマル(すてき)な方法をクローズすることを可能にします。
いくつかのポイント。 ThreadAbort例外は、スレッドが中断されます理由です。それはアボート呼び出しあなたの副作用ではありません。 あなたがスレッドで中止呼び出すと、ランタイムはスレッドに伝播されるようにthreadabort例外を強制します。スレッドがアボートする前に、それは、ユーザがいくつかのクリーンアップを実行することができますので、この例外をキャッチすることができます。
の例外は、スレッドが中断されることを保証するために自動的に再スローされます。例外がキャッチされ、それが再スローされなかった場合は、スレッドが中断したことがないかどうます。
実際に本当にインテリジェントデザインます。
だから、その例外をキャッチするために本当にOKです。実際にあなたがする必要があります。しかし、それだけで特定の例外ではなく、一般的な例外をキャッチ。 (以下に示すように)
catch(ThreadAbortException ex)
{
//This is an expected exception. The thread is being aborted
}
のThreadAbortExceptionののに例外の種類を変更し、をResetAbort()の
に呼び出しを追加 try
{
Program.splashThread.Abort();
}
catch(ThreadAbortException ex)
{
Thread.ResetAbort();
}
一般的には、スレッドを中止することは非常に悪い習慣とみなされ、バグを追跡するのは難しいのすべての種類につながることができます。あなただけの のスプラッシュウィンドウを閉じるかのポーリングのフラグが設定されている場合、スレッドを停止する?
のいくつかの並べ替えを使用する方法を考え出す検討していますなぜあなたはそれを行うだろうか?ただ、スレッドがそれを拾ったときに、最終的に、それは自分自身を閉じます、そのスレッドのポーリングフラグを設定します。
このコードを試してみてください。それは私のために正常に動作しています。
void splash()
{
try {
SplashScreen.SplashForm frm = new SplashScreen.SplashForm();
frm.AppName = "HR";
Application.Run(frm);
}
catch (ThreadAbortException ex)
{
Thread.ResetAbort();
}
}
私はフレドリックモルクによって提案されたソリューションを使用しました。それは非常に明確でエレガントです。 私たちは実際のアプリケーションを起動する前に、スプラッシュフォームをインスタンス化しそうでない場合、私は問題を発見した(application.run(MainFormを...)):
これは、フォームのハンドルがまだない呼び出し元スレッド内に存在によって引き起こさinvalidOprationExceptionを発生させます。 (!と、この例外をスキップ)スレッドtで直接ハンドルを作成するには、このようにスプラッシュフォームを起動しようとします:
Thread t = new Thread(new ThreadStart(delegate
{
_splash = new Splash();
Application.Run(_splash);
}));
t.Start();
と、あなたは、プログラムのより多くの枝にcloseSplashメソッドを呼び出して最初の呼び出しの後にNULL値を強制することを計画している場合:
private static Splash _splash = null;
public static void CloseSplash()
{
if (_splash!= null)
{
_splash.CloseSplash();
_splash=null;
}
}