How to suppress C # thread.abort () error?

I show a splash screen in the background thread while my program loads. As soon as it loads, I abort Thread, as the only goal was to show the Now Loading popup window shape.

My problem is that when the thread is interrupted, it throws a ThreadAbortException , which the user can simply click Continue.

How can I handle this? I tried to crush him like this: β†’

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

but I have a feeling that I will scream here and it won’t work.

Thanks!

+4
source share
8 answers

You do not need to cancel the stream. I will give an example with the code.

In the form of a splash screen:

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

In the Program.cs file:

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

Now that your main method starts, show a splash in the stream:

 Thread t = new Thread(new ThreadStart(delegate { _splash = new Splash(); _splash.ShowDialog(); })); t.Start(); 

... and when you want it to close, just close it:

 Program.CloseSplash(); 

Then you do not need to worry about interrupting the flow; he will gracefully go out.

+20
source

Please refer to the following link from a Google search (first result returned):

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

Pay particular attention to this part:

When this method is called on a thread, the system throws a ThreadAbortException into the thread to abort it. ThreadAbortException is a special exception that can be caught by application code, but re-thrown at the end of the catch block if ResetAbort is not called. ResetAbort cancels the interrupt request and prevents ThreadAbortException from terminating. Unfinished finally blocks are executed before the thread is interrupted.

+9
source

Using Threadbort is not recommended. This evil. Why not use another mechanism, such as (Auto / Manual) ResetEvent? Start the stream using the screensaver, wait for the event. If other code is executed with loading, set the en event so that the splash screen closes itself in the usual (pleasant) way.

+7
source

Some moments. ThreadAbort exception is the reason the thread is interrupted. This is not a side effect that you cause. When you call an interrupt in a thread, the runtime causes the threadabort exception to be thrown into the thread. This exception can be caught because it allows the user to do some cleanup before the flow stops.

Then the exception is automatically restored to ensure that the thread is interrupted. If the exception was caught, and if it was not recovered, the thread was never interrupted.

Really intelligent design really.

So it’s normal to catch this exception. Actually you should. But catch only this particular exception, not the general exception. (as shown below)

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

Change the exception type to ThreadAbortException and add a call to ResetAbort ()

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

In general, thread interruption is considered very bad practice and can lead to all sorts of difficulties in tracking errors. Have you considered a way to simply close the splash window or use some kind of polling to stop the flow when setting the flag?

+3
source

Why would you do this? Just set a flag that polls the stream, and then when the stream picks it up, it will close.

+1
source

Try this code. It works great for me.

 void splash() { try { SplashScreen.SplashForm frm = new SplashScreen.SplashForm(); frm.AppName = "HR"; Application.Run(frm); } catch (ThreadAbortException ex) { Thread.ResetAbort(); } } 
+1
source

I used the solution suggested by Fredrick Merck. It is very clear and elegant. Otherwise, I found the problem if we create a splash form before running the real application (application.run (mainform ...)):

it throws an invalidOprationException, caused by the fact that the descriptor form does not yet exist in the calling thread. To create a descriptor directly in thread t (and skip this exception!), Try running the splash form as follows:

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

and if you plan to call the closeSplash method in more branches of the program, force a null value after the first call:

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

Source: https://habr.com/ru/post/1285753/


All Articles