0

Using a delegate, I'm calling an objects ("o") method ("ProcessElement") which returns an int:

int result;
object o;
...
if (o != null) {
    try {
        Func<int> processElement = 
            (Func<int>)Delegate.CreateDelegate(
                typeof(Func<int>), 
                o, 
                "ProcessElement");
        result = processElement();
    } catch (Exception) {
        throw;
    }
}

This works great until I encounter an exception.

When I encounter an exception, Visual Studio throws an error stating that the exception was unhandled. I have a try/catch surrounding the delegate. Should this not catch the exception?

ProcessElement method:

public int ProcessElement () {
    throw new ApplicationException("test");
}

Visual Studio Error:

ApplicationExcpetion was unhandled

Thanks,

EDIT: Perhaps I'm not beging totally clear- Sorry. I know you can't copy and paste to test, but at any rate, here is more of the story:

static void Main (string[] args) {
    try {
        Thread processThread = new Thread(ExecuteConfiguration);
        processThread.Start();
        if (!processThread.Join(TimeSpan.FromMilliseconds(int.Parse((_Configuration2.TimeOutMinutes * 60 * 1000).ToString())))) {
            processThread.Abort();
            Status = Program.BatchJobsStatus.TimeOut;
            throw new ApplicationException("Time out");
        }
    } catch (Exception ex) {
        //Expecting to catch error thrown in ExecuteConfiguration -> SendEmail here.
        Logger.WriteErrorMessage("\n" + ex.ToString());
    }
}

private static void ExecuteConfiguration () {
    for (int i = 0; i < ElementCount; i++) {
        if (ContinueProcessing) {
            object o = GetConfigurationElementById(_Configuration2, "ElementId", i.ToString());
            if (o != null) {
                MethodInfo method = o.GetType().GetMethod("ProcessElement");
                if (method != null) {
                    try {
                        Console.WriteLine("(ElementId " + i.ToString() + ") " + o.GetType().FullName);
                        Func<int> processElement = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), o, method);
                        i = processElement();
                    } catch (Exception) {
                        // rethrow error thrown in SendEmail
                        throw;
                    }
                } else {
                    Console.WriteLine("(ElementId " + i.ToString() + ") " + o.GetType().FullName + " method ProcessElement does not exist");
                }
            }
        }
    }
}

public int ProcessElement () {
    int result = ElementId;
    SendEmail(); // error thrown here, resulting in "Exception was unhandled" error in calling method (ExecuteConfiguration)
    for (int i = ElementId + 1; i < Program.ElementCount; i++) {
        if (Program.ContinueProcessing) {
            object o = Program.GetConfigurationElementById(this, "ElementId", i.ToString());
            if (o != null) {
                MethodInfo method = o.GetType().GetMethod("ProcessElement");
                if (method != null) {
                    try {
                        Console.WriteLine("(ElementId " + i.ToString() + ") " + o.GetType().FullName);
                        Func<int> processElement = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), o, method);
                        result = processElement();
                    } catch (Exception) {
                        throw;
                    }
                } else {
                    Console.WriteLine("(ElementId " + i.ToString() + ") " + o.GetType().FullName + " method ProcessElement does not exist");
                    result = i;
                }
            }
        }
    }
    return result;
}

public void SendEmail() {
    throw new ApplicationException("test");
}

I would expect the error to bubble up to "Main", because that is my top level try/catch, but it does not. Instead, I get "ApplicationExcpetion was unhandled" in "ExecuteConfiguration".

Michael
  • 434
  • 1
  • 5
  • 12
  • 1
    Did you correct a typo or did you edit in the answer? Does the current code still produce the error? – H H Apr 30 '13 at 18:22
  • Cemafor's answer below threw me off and I removed my "throw;" statement from my original post. I've since added it back in because in the end I need to rethrow the error. The question as it currently stands does not work. – Michael Apr 30 '13 at 18:41
  • @Michael: You need to catch and not throw the exception at some point. Any exception that makes it all the way to VS is considered unhandled, even if it did pass throw a try/catch. I'm not sure why you *need* to rethrow the exception, but you can put a try/catch arround the whole main function to prevent VS from displaying the exception. – Cemafor Apr 30 '13 at 18:57
  • Thanks for your diligence, Cemafor. I've further edited my question which should hopefully provide more context for my problem. – Michael Apr 30 '13 at 19:13
  • 1
    Ahh, a second thread emerges... Take a look [here](http://stackoverflow.com/questions/5983779/catch-exception-that-is-thrown-in-different-thread) – Cemafor Apr 30 '13 at 19:18
  • Cemafor, the [link](http://stackoverflow.com/questions/5983779/catch-exception-that-is-thrown-in-different-thread) you provided was very helpful. Thanks! – Michael Apr 30 '13 at 19:51

1 Answers1

3

You are catching then immediately throwing it again. You should handle it appropriately.

try {
    Func<int> processElement = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), o, "ProcessElement");
    result = processElement();
} catch (Exception) {
    //ignore the exception (not recomended)
}
Cemafor
  • 1,633
  • 12
  • 27
  • if I remove the try/catch, I still get the "unhandled" error from the method I'm calling... this line here: result = processElement(); – Michael Apr 30 '13 at 17:58
  • You need to keep the try/catch in place. If you removed only the `throw;`, like your edited code suggests, the catch should be catching your exception and then just continuing execution. – Cemafor Apr 30 '13 at 18:18
  • I agree, but what if you want to rethrow the exception so an outer try/catch can process? Not possible? If I remove the try/catch, unhandled error occurs. If I try and rethrow, unhandled error occurs. – Michael Apr 30 '13 at 18:21
  • You can use `throw;` to rethrow (this is the suggested method if that is what you want to do, rather than `throw e;`), you just need to make sure there is another try/catch to catch it. If it is getting to VS then there is no other catch at a higher level. – Cemafor Apr 30 '13 at 18:26