2

I am currently working in .net c# 4.0 and have come across an issue with some code that I written that is causing me some headaches.

I am using the System.Threading.Tasks.TaskFactory class in conjunction with System.Threading.Tasks.TaskScheduler to start a new thread in my console application where the function of the thread is to check if an item has been added to a queue. When an item is added to the queue, it processes it.

So the queue contains emails to be sent and once an email is added to the queue, the email is sent via multiple clients. The sending to each is done in parallel.

I have this intermittent issue where the following exception occurs in the new thread some of the time:

[System.Threading.ThreadAbortException] = {Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}

When debugging I am not able to get any further information as all properties in the stack have "Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack."

Looking on the internet for a solution, I have found this is an issue that occurs when doing a response.redirect but I am not doing this in my code. If I try to debug, there is no consistency as to where this error occurs. Following is the code I use to create the factory and start the new thread:

    this.taskFactory = new TaskFactory(TaskScheduler.Current);
    this.taskFactory.StartNew(this.DequeueMessage, state, TaskCreationOptions.LongRunning);

Has anyone any pointers as to why I may be getting this error and any tips as to how it might be fixed?

amateur
  • 43,371
  • 65
  • 192
  • 320
  • 1
    Are you creating the Tasks in a web app? If so, you are probably seeing the AppDomain being recycled. The solution is to move your background threads into a windows service. – Nick Butler Jul 17 '12 at 18:00
  • I am seeing this behaviour in a simple integration test I am running in visual studio. Also see same behaviour when I run the same code in a console application. – amateur Jul 17 '12 at 18:11

1 Answers1

3

The only reason that you get a ThreadAbortException is because Thread.Abort was called on the thread. If you're not doing that manually, this can happen in a client application when it terminates. It will also happen in hosted environments when things get recycled. If you provide more detail, a more specific answer could be provided.

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
  • 2
    I am calling this code via an integration test written with the aid of micrsoft visual studio testing framework. It has just dawned on me that when I run the test, it completes before the code has fully executed, hence the Thread.Abort. Could this be possible? – amateur Jul 17 '12 at 19:05
  • 2
    @amateur Yes, that's exactly what is happening. The testing process is existing before the background thread has completed. In your test you need to "wait" until the background thread is completed before exiting from the test. You can do this with Task.Wait() (StartNew returns a Task object) – Peter Ritchie Jul 17 '12 at 19:15
  • Ah - cant believe it has only just dawned on me now! It was your response that got me thinking! When I call the Wait method on the Task object returned, the task seems to go in to a state where it does nothing, no processing, just sits there idle. Any idea why this may be the case? – amateur Jul 17 '12 at 19:31
  • @amateur Wait is fairly simple. If the task is already running, Wait simply waits for the task to complete (i.e. your delegate). If it isn't already running, Wait causes the task to execute then waits for it to complete. There's nothing inherent in Task.Wait that would affect whether your delegate will be idle or not – Peter Ritchie Jul 17 '12 at 19:50