2009-06-04 8 views
4

私のプログラムが読み込まれている間、背景スレッドにスプラッシュ画面が表示されています。それがロードされると、スレッドを中止するのは、Now Loadingのスプラッシュフォームを表示することだけです。thread.abort()エラーを抑制するにはどうすればいいですか?

私の問題は、スレッドを中止するときにユーザーがただ続行をクリックすることができるThreadAbortExceptionを投げるということです。

どうすればこの問題に対処できますか? >

  try 
     { 
      Program.splashThread.Abort(); 
     } 
     catch(Exception ex) 
     { 

     } 

が、私は私がここに怒鳴らを取得しようとしている気持ちを持って、それがどのように動作しません - 私はそうのようにそれを抑制しようとしていました。

ありがとうございます!一般的にThreadAbortExceptionの

+4

私は実際にスプラッシュ画面の作成についてブログに書きました。これがあなたを助けることができるかどうかを見てください:http://crazorsharp.blogspot.com/2009/06/creating-splash-screen-in-net-with.html BFree

+2

あなたがThread.Abortを使用する必要がある場合は、何かが間違っている(一般的に)。より安全で安全な方法を探してみてください。以下にたくさんの良い提案があります。 –

+1

@BFree:もし私が答えが分かれば、私はあなたに答えを与えるだろう!建設的なフィードバックをありがとう。私はあなたのポストから既に多くのことを学んでいます!他の答えは私の現在の解決策を私はあなたのブログの情報からより堅牢なスプラッシュを作成することを期待して仕事を得ている間。ありがとうございました! –

答えて

20

スレッドをキャンセルする必要はありません。私はコードを例に説明します。プログラムの中で

public void CloseSplash() 
{ 
    Invoke((MethodInvoker)delegate 
    { 
     this.Close(); 
    }); 
} 

:スプラッシュ画面フォームで

。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(); 

スレッドを中止する心配はありません。それは優雅に終了します。

+2

これを行うにはより良い方法を教えていただきありがとうございます。建設的なフィードバックは非常に高く評価されています! –

3

変更例外タイプとResetAbort(への呼び出しを追加)

try 
    { 
     Program.splashThread.Abort(); 
    } 
    catch(ThreadAbortException ex) 
    { 
     Thread.ResetAbort(); 
    } 

、スレッドを中止することは非常に悪い習慣とみなされ、追跡するのは難しいのすべての種類につながることができますバグ。 スプラッシュウィンドウを閉じるか、ポーリングのようなフラグを設定してスレッドを停止する方法を考えたことがありますか?

+0

スプラッシュフォームを閉じて、スレッドが行っていたすべてのスレッドは、スレッドを破棄しますか? –

9

次のリンクを参照してくださいは、(最初​​の結果が返される)Google検索を行って得た:

http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx

は、この部分には特に注意してください:

このメソッドがスレッド上で呼び出されると、システムはスレッド内でThreadAbortExceptionをスローして中止します。 ThreadAbortExceptionは、アプリケーションコードによって捕捉される特殊な例外ですが、ResetAbortが呼び出されない限り、catchブロックの最後に再スローされます。 ResetAbortは中止要求をキャンセルし、ThreadAbortExceptionがスレッドを終了させないようにします。未実行のfinallyブロックは、スレッドがアボートされる前に実行されます。

+0

私はちょうどこれを投稿しようとしていました。言い換えれば、彼がやりたいことはおそらく不可能です。 –

1

なぜそれをしますか?スレッドがポーリングするフラグを設定すると、スレッドがそれをピックアップすると、それ自体が閉じます。

7

Threadabortの使用は推奨されません。それは悪です。 (Auto/Manual)ResetEventのような別のメカニズムを使用してみませんか? スプラッシュ画面でスレッドを開始し、イベントを待ちます。他のコードの読み込みが完了している場合は、イベントを設定して、スプラッシュスクリーン自体を通常の(良い)方法で閉じることができます。

+0

私の口からすぐに言葉を取り出しました;-)私はそのThread.Abort()を書くつもりでしたが、悪です。 –

4

いくつかの点があります。 ThreadAbort例外はスレッドがアボートする理由です。それはあなたの中止を呼び出す副作用ではありません。 スレッドでアボートを呼び出すと、ランタイムはスレッドにスレッド例外を伝播させます。この例外は、ユーザーがスレッドを中止する前にクリーンアップを実行できるため、検出されます。

例外が自動的に再スローされ、確実にスレッドがアボートされます。例外がキャッチされ、スレッドが再スローされなかった場合、スレッドは決して中断しません。

実際にインテリジェントなデザイン。

だから、その例外を捕まえることは本当に問題ありません。実際はあなたはすべきです。しかし、特定の例外のみを捕捉し、一般的な例外は捕捉しません。 (下に示すように)

catch(ThreadAbortException ex) 
{ 
    //This is an expected exception. The thread is being aborted 
} 
+0

ありがとうございます! –

0

私はFredrikMörkによって提案されたソリューションを使用しました。それは非常に明確でエレガントです。 実際のアプリケーション(application.run(mainform ...))を起動する前にスプラッシュフォームをインスタンス化すると、問題が見つかりました。

フォームハンドルによってinvalidOprationExceptionが発生しましたが、糸。 スレッドtで直接ハンドルを作成(およびこの例外をスキップ!)このようにスプラッシュフォームを起動しようとする:あなたは、プログラムのより多くの枝にcloseSplashメソッドを呼び出すために計画している場合、

Thread t = new Thread(new ThreadStart(delegate 
{ 
    _splash = new Splash(); 
    Application.Run(_splash); 
})); 

t.Start(); 

と最初の呼び出し後にヌル値を強制します。

private static Splash _splash = null; 
    public static void CloseSplash() 
    { 
     if (_splash!= null) 
     { 
      _splash.CloseSplash(); 
      _splash=null; 
     } 
} 
1

このコードを試してください。それは私のためにうまくいきます。

void splash() 
{ 
    try { 
     SplashScreen.SplashForm frm = new SplashScreen.SplashForm(); 
     frm.AppName = "HR"; 

     Application.Run(frm); 
    } 
    catch (ThreadAbortException ex) 
    { 
     Thread.ResetAbort(); 
    } 
} 
関連する問題