i need help with catching exceptions in C#. I have a Windows service which is acting like a wrapper for other modules, so to not have multiple Windows Services i start all modules/agents thats how we call them in that Wrapper Windows Service. Each of this 'agent' is started in a own Task. I am not in control what the agent itself is doing so it can be and will from time to time is such a agent starting also a task or thread and if there an exception is getting thrown, i am not able to catch it. I tried different things but was not able to do so. So if such a exception occurs in production my whole service is crashing and all agents with it, which is a nightmare. I try to simplify it with an example code:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
AppDomain.CurrentDomain.UnhandledException += (o, e) =>
{
Console.WriteLine("CurrentDomain Unhandled Exception: {0}", e.ExceptionObject);
};
TaskScheduler.UnobservedTaskException += (s, e) =>
{
Console.WriteLine("TaskScheduler.UnobservedTaskException Unhandled Exception: {0}", e.Exception);
e.SetObserved();
};
Task.Factory.StartNew(() =>
{
Task.Factory.StartNew(() => throw new Exception("I am a exception ! Catch me !"));
}, TaskCreationOptions.LongRunning)
.ContinueWith((t) =>
t.Exception.InnerExceptions.ToList().ForEach(e => Console.WriteLine("Error executing task.{0}", e)),
TaskContinuationOptions.OnlyOnFaulted);
Console.WriteLine("If you read this, application is not crashed!");
Console.ReadKey();
Task.Factory.StartNew(() =>
{
throw new Exception("I am a exception ! Catch me !");
});
}
}
So how to catch the exception ? It will not get fetched by any of my handlers.
Important is that i have no influence of that part of code, thats my 'agent' :
Task.Factory.StartNew(() => throw new Exception("I am a exception ! Catch me !"));
Everything else i am able to change.
Edit: unfortunately provided solution seems to not work for me. I am still not able to catch the exception which occurs. Maybe its getting more clear when i show my original code:
private async Task StartAgent(IAgent agent)
{
_logger.LogInfo("Agent starting with instanceId {0}", agent.GetInstanceGuid());
if (agent == null)
{
throw new ArgumentNullException("agent");
}
try
{
Task task = await Task.Factory.StartNew(async () =>
{
agent.Start();
}, TaskCreationOptions.LongRunning);
await task.ContinueWith((t) =>
{
var aggException = t.Exception.Flatten();
foreach (var exception in aggException.InnerExceptions)
_logger.LogError("Error executing agent task.{0}", exception, t.Id);
}, TaskContinuationOptions.OnlyOnFaulted);
_agents[agent.GetInstanceGuid()].Task = task;
_agents[agent.GetInstanceGuid()].LastTaskStatus = task.Status;
}
catch (Exception e)
{
_logger.LogError("Exception in Agent Task.",e);
}
}
So the agent.Start() is what i am calling in the task everything what happens inside i don't know. The agent can create tasks, threads everything he wants. Start() is also void and i can't change the interface to await it.