1

The following code seems as though it should swallow any type of exception in the try block, but the IIS worker process periodically dies and restarts because of an unhandled exception (marked with a comment.)

try
{
    while (true)
    {
        DispatcherTask task = null;

        lock (sync)
        {
            task = this.getTask();

            if (task == null)
            {
                Monitor.Wait(sync);
                continue;
            }
        }

        lock (task)
        {
            task.Result = task.Task.DynamicInvoke(task.Params);
            // ^ Delegate.DynamicInvoke(object[]) throws a TargetInvocationException

            Monitor.PulseAll(task);
        }
    }
}
catch (Exception e)
{
}

UPDATE:

Definition of DispatcherTask:

private class DispatcherTask
{
    public Delegate Task;

    public object[] Params;

    public object Result;
}
Jesse C. Slicer
  • 19,901
  • 3
  • 68
  • 87
tuespetre
  • 1,827
  • 2
  • 18
  • 30
  • 5
    Because the task is spawning a new thread which exists outside the the scope of your try/catch. – Brad M Aug 22 '13 at 21:14
  • 3
    More specifically, it would be because the exception is being thrown in separate thread. It does not really matter if you a spawning a new thread or not in your code/ – Gary Walker Aug 22 '13 at 21:19
  • The `DispatcherTask` in this case is actually just a `Delegate`, are you really sure that calling `Delegate.DynamicInvoke(object[])` spawns a new thread? If that were the cause, we could never catch the `TargetInvocationException`... – tuespetre Aug 22 '13 at 21:20
  • The `try/catch` surrounds the **creation** of the second thread. It doesn't surround the **execution** of that thread. –  Aug 22 '13 at 21:22
  • Amy, I would understand that, but I just don't see *where* I am creating the second thread within that try/catch block, not to mention the fact that it is `DynamicInvoke` that throws the exception. – tuespetre Aug 22 '13 at 21:24
  • Please excuse me. I saw `Task` in the code and my immediate thought was "oh, tasks... threads!". –  Aug 22 '13 at 21:33
  • I understand... I didn't put the definition of that class in my question until after it had been posted for a little bit. My fault – tuespetre Aug 22 '13 at 21:33
  • 1
    I understand your question and I don't know the answer, but what is the content of the InnerException of TargetInvocationException ? – Mark Lakata Aug 22 '13 at 21:49
  • See this answer: http://stackoverflow.com/questions/3599078/uncatcheable-exception-from-methodinfo-invoke – Mark Lakata Aug 22 '13 at 21:52
  • @Mark Lakata, I am not sure what the InnerException is because I can't catch the TargetInvocationException for some reason. :( In my real code, I have logic in the catch block. – tuespetre Aug 22 '13 at 21:54
  • @tuespetre can you run it under the VS debugger and view the exception details (including InnerException) there? – Jesse C. Slicer Aug 22 '13 at 22:28
  • Unfortunately it only occurs sporadically in a live/production environment. I don't know of a way to reproduce it. – tuespetre Aug 22 '13 at 22:34
  • 1
    If your app is in production/live, try to open a support case via http://support.microsoft.com . Generally speaking, via a debugger such WinDbg and a few tricks you can capture a process dump when this exception occurs, and then by analyzing the dump everything will be clear. You might in the future include ELMAH in your app, and that should provide more information for your next troubleshooting task, http://code.google.com/p/elmah/ – Lex Li Aug 23 '13 at 02:52
  • Apparently, a type of exception that will bypass catch blocks in .NET 4 and up by default is `System.AccessViolationException`. A server admin gave me the Windows event log for that server and right after the `TargetInvocationException` error log he shared with me was a `System.AccessViolationException` information log from Windows Error Reporting for every crash. I could enable catching of that exception in Web.config, but really, I need to fix whatever is happening in my code that could cause that, and I already have an idea. – tuespetre Aug 23 '13 at 13:07

2 Answers2

2

You cannot catch the exceptions of another thread, at least not in this way. Catch your exception inside the newly opened thread and you will be fine.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • I'm sorry but I do not think that I am opening another thread. The `catch` block should be in the same thread in which the `Delegate` is dynamically invoked... I might need a fuller explanation if I'm missing something here. – tuespetre Aug 22 '13 at 21:22
  • The words "sync", "wait", "DynamicInvoke" makes me think that you are opening new threads even if you are not aware of that. – Lajos Arpad Aug 23 '13 at 14:32
  • Ah, I understand. It turned out the issue was an `AccessViolationException`, which bypasses catch blocks in .NET 4/4.5 by default. Thanks for your help anyway. – tuespetre Aug 23 '13 at 14:54
  • If my answer was helpful to you, please accept it, as people in the future will see that exceptions inside a thread cannot be catched in the thread starting the thread where the exception occurred. – Lajos Arpad Aug 24 '13 at 13:16
  • I'm sorry, the problem was not because the exception was thrown in a new thread. But thank you for trying to help! – tuespetre Aug 24 '13 at 16:26
0

In .NET 4 and up, AccessViolationException will bypass catch blocks by default. Catching of such exceptions can be enabled in web.config, but should not be, as they typically result from errors in unmanaged code and signal that the application state is corrupted.

tuespetre
  • 1,827
  • 2
  • 18
  • 30