1

We are running a long job (function) in 3-4 different threads. All running threads got successfully completed but sometimes the exception Thread was being aborted is being thrown by one of the thread which results all threads to stop. Below is sample code for what we are actually doing in our application.

List<Thread> lstThreads = new List<Thread>();
foreach(int 0; i < 4; i++)
{
  Thread th = new Thread(() => {
    RunLongRunningJob(i);
  });
  lstThreads.Add(th);
}
foreach (Thread th in lstThreads)
  th.Start();

We are calling rest api's, writing in files and update database records in RunLongRunningJob.

P.S. We are not using LOCKS, is this could be the reason?

Util
  • 191
  • 1
  • 5
  • 1
    "which results all threads to stop". It shouldn't. Are you sure you're not terminating the application or something like that? Do you have **any** code that calls Abort on threads? If not, then I'd say that no threads should terminate with that kind of problem, at all. – Lasse V. Karlsen Feb 28 '20 at 11:15
  • 2
    Also, "not using locks" is not enough to judge whether this will cause problems. If you're sharing data structures that aren't thread safe, it may cause threads to throw an exception, but it will not cause threads to "be aborted". When a thread is aborted it is because a thread was explicitly asked to abort using the Abort method on the thread object. If a thread throws an exception, it will terminate, but it will not "be aborted". – Lasse V. Karlsen Feb 28 '20 at 11:18
  • Are you using ASP.NET? If so: https://stackoverflow.com/questions/7629986/why-am-i-getting-thread-was-being-aborted-in-asp-net – Matthew Watson Feb 28 '20 at 11:19
  • I doubt your sample code is actually recreates the problem. If one thread kills the rest of the app, then that is different to one thread kills the other threads but the app still runs. – Neil Feb 28 '20 at 11:19
  • @MatthewWatson I don't believe this applies to secondary threads. I might be wrong, however. It may be that they join on all the threads, and the main thread was aborted due to such a Response.Redirect, but then the main thread could not be in a Join call anyway because it is the thread that is running the Redirect that will be aborted, and thus it can't be simultaneously sitting in a Join call. – Lasse V. Karlsen Feb 28 '20 at 11:19
  • @LasseV.Karlsen, i guess you are right that the application got terminated. We provide frequent updates on application which stop the application for some seconds which results in `ThreadAbortException`. But we also saw the same exception when we are not uploading anything on the application server. – Util Feb 28 '20 at 12:49
  • Is there any configuration on the IIS that result our application to restart for some reason? – Util Feb 28 '20 at 12:55
  • Why does people assume this is IIS? There is no indication that this is a web application of any form. Without knowing which type of application this is, and probably without seeing more code such as the main application code, there is no way for us to guess why the application might terminate. Your best option is to add logging into the mix and see if you can catch the reason. My best guess would be an exception in the right place. – Lasse V. Karlsen Feb 28 '20 at 20:24

1 Answers1

3

In C#, threads can not be stopped at all without side effects. Imagine the thread has disposable items ready and - just stops. As a workaround, when a thread gets aborted (which you an - you should not, but you can call on the Thread object) a ThreadAbortException is generated and executed. This allows exception handling to kick in and close file handles etc.

Ah, finally found it - this is the blog post explaining why YOU should never call Thread.Abort (i.e. it should not be called by application code):

http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation

This is about timing and the thread not actually executing finally properly in really bad cases.

Now, SOMETHING must find out what causes the thread to be aborted. This is something to check - exception details would help, including the stack trace and possible inner exception in it.

TomTom
  • 61,059
  • 10
  • 88
  • 148
  • Actually, aborting a thread that has proper try/catch/using blocks to handle disposable items will in fact run Dispose before the exception bubbles further. The advice to not call Abort is correct though, it is a low level method intended for the framework, not for user code. – Lasse V. Karlsen Feb 28 '20 at 11:23
  • 2
    * It will call dispose BECAUSE the abort is handled as an exception with the help of ThreadAbortException. * There are other side effects of thread.abort. Editing in. – TomTom Feb 28 '20 at 11:24
  • @TomTom, thanks for your valuable answer. But i guess our application restarted which is resulting the threads to abort. Is there anything we can look why the app restarts randomly. Because it happened only sometimes not on the regular basis. – Util Feb 28 '20 at 12:58
  • Logging. Certain unhanlded exceptions may lead to an appliction stopping, particularly under IIS - but it should leave a log entry in the event logs. Add instrumentation - we dump all activieis to MS Azure Application Insights. – TomTom Mar 02 '20 at 10:50