Handle Error for Task.Factory.StartNew - c#

I am facing issue when i got exception in threading. My Code is as follows:
Task.Factory.StartNew(() => ComputeBackgroundAdjudicationTask(taskId, ComputeBackgroundAdjudication));
And ComputeBackgroundAdjudicationTask method is as follows:
private void ComputeBackgroundAdjudicationTask(long taskId, Action<int> completedAdjudicationJobHandler)
{
//My Logic
completedAdjudicationJobHandler(1);
}
Now what iam facing issue is in my logic suppose some exception is coming i want to log into some text file.
After i searched in net i found some answer is as follows.
Task.Factory.StartNew(() =>ComputeBackgroundAdjudicationTask(taskId, ComputeBackgroundAdjudication))
.ContinueWith(
task =>
{
if (task.Exception != null)
task.Exception.Handle(ex =>
{
System.IO.File.AppendAllText(#"C://test.txt", "Error:" + ex.Message + "\r\n");
return true;
});
}, TaskContinuationOptions.OnlyOnFaulted
);
Now its logging into text file. After logging into text file the thread is not starting again. Please help me to fix this.
Thanks in Advance.

In your example the exception terminates the task/thread and after that you log the cause of the thread termination.
It seems what you are searching for is more of this kind:
private void ComputeBackgroundAdjudicationTask(long taskId, Action<int> completedAdjudicationJobHandler)
{
while(true) {
try {
//My Logic
completedAdjudicationJobHandler(1);
}
catch(Exception ex) {
System.IO.File.AppendAllText(#"C://test.txt", "Error:" + ex.ToString() + "\r\n");
}
}
}
But this seems as if whatever completedAdjudicationJobHandler does is not really well designed.
I want to add: If whatever throws the exception will always throw the exception this leads to an infinite loop.
Edit 2016-01-07: Maybe I misunderstood the wanted effect again. As I understand the last comment you want to do things written at the position of // MyLogic and whether they fail or succeed want completedAdjudicationJobHandler(1); executed. In this case the code example would be:
private void ComputeBackgroundAdjudicationTask(long taskId, Action<int> completedAdjudicationJobHandler)
{
try {
//My Logic
}
catch(Exception ex) {
System.IO.File.AppendAllText(#"C://test.txt", "Error:" + ex.ToString() + "\r\n");
}
finally {
completedAdjudicationJobHandler(1);
}
}

Related

How to catch an exception only if another exception as not occured in C#

So I'm a student in programming and I want my code to do a try-catch on an exception but ONLY if another exception as not occured. Let me show you want I did:
using (var ctxInsert = new model())
{
CATEGORIES c1 = new CATEGORIES(6, "cat6", "category6");
Console.WriteLine("Please wait while rows are added to tables...");
//first try-catch to know if the new entry exist
try
{
ctxInsert.CATEGORIES.Add(c1);
}
catch (ModelValidationException e1)
{
Console.WriteLine(e1.Message);
Console.WriteLine("Category already exist");
}
//second try-catch to make sure saving changes to table is succesful
try
{
ctxInsert.SaveChanges();
Console.WriteLine(c1.NAME + " : Succesfuly added");
}
catch (DbEntityValidationException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("not done");
}
}
Console.ReadLine();
So what I'm trying to do is that the second try-catch block only runs if the first DIDN'T catch an exception. Cause right now, like this, both try-catch runs and it doesn't make sense to save changes if the first one catches an exception.
I tried a bunch of things on my own but nothing works...
If you need just to make your code working as you expected, you can write like this:
using (var ctxInsert = new model())
{
CATEGORIES c1 = new CATEGORIES(6, "cat6", "category6");
Console.WriteLine("Please wait while rows are added to tables...");
//first try-catch to know if the new entry exist
try
{
ctxInsert.CATEGORIES.Add(c1);
ctxInsert.SaveChanges();
Console.WriteLine(c1.NAME + " : Succesfuly added");
}
catch (ModelValidationException e1)
{
Console.WriteLine(e1.Message);
Console.WriteLine("Category already exist");
}
catch (DbEntityValidationException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("not done");
}
}
Console.ReadLine();
BUT, I'd rather write code without any try/catch but make exception interceptors on top level of your application (There are best practices, depending on what framework you are using)
The whole point of a try-catch is to stop an exception from preventing the rest of your code from executing. In your case, there are a few options I see off the top of my head:
Decide whether a try-catch is really what you're looking for - you could also have your method throw an exception and prevent execution of the rest of the code
Throw an exception in your catch, that way you get your logs and it tells the rest of the code that something went wrong, preventing execution
Use a variable which gets modified by the first catch, then conditionally execute the rest of the code based on that variable
Use a try-catch-finally
yes you can use the finally keyword let me show you with code example
using System;
namespace ErrorHandlingApplication {
class DivNumbers {
int result;
DivNumbers() {
result = 0;
}
public void division(int num1, int num2) {
try {
result = num1 / num2;
} catch (DivideByZeroException e) {
Console.WriteLine("Exception caught: {0}", e);
} finally {
Console.WriteLine("Result: {0}", result);
}
}
static void Main(string[] args) {
DivNumbers d = new DivNumbers();
d.division(25, 0);
Console.ReadKey();
}
}
}

WinForms App hangs after invoking a delegate from other thread

i have a problem with Winforms app with 2 threads: in a second thread I pull messages from WCF service. When there are messages I need to update the GUI : I do this in accordance with patten found here How to update the GUI from another thread in C#? . Here is the code:
private delegate void CWU(int ID);
public void AddNewTab(int id)
{
if (this.tabControl1.InvokeRequired)
{
CWU cb = new CWU(AddNewTab);
this.tabControl1.Invoke(cb,id);
}
else
{
User ToChatWith = ContactsHelper.AllFriends.Find(e => e.ID == id);
tabpage.Text = ToChatWith.ToString();
this.tabControl1.TabPages.Add(tabpage);
this.tabControl1.SelectTab(tabpage);
}
tab is added properly and when we leave this method the app is not responding, no info in debug. When I run my app after adding this tab i get AppHangB1 without any details. Can you help me?
Try this:
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
AddNewTab(id);
});
}
Invoke can hang if the called thread is busy doing something. (You could know this is the case if a BeginInvoke call instead of your Invoke wouldn't hang. Invoke blocks until the call is made successfully, BeginInvoke does not.)
Replace your method with this:
private void dbg(string s)
{
System.Diagnostics.Debug.WriteLine("AddNewTab({0}): {1}",
Thread.CurrentThread.ManagedThreadId, s);
}
public void AddNewTab(int id)
{
try
{
dbg("entered");
if (this.tabControl1.InvokeRequired)
{
new Thread(delegate() { try {
CWU cb = new CWU(AddNewTab);
dbg("calling Invoke");
this.tabControl1.Invoke(cb, id);
dbg("Invoke returned");
} catch (Exception ex) { dbg("" + ex); }
}).Start();
dbg("created sub-thread");
}
else
{
dbg("setting tabpage.Text");
User ToChatWith = ContactsHelper.AllFriends
.Find(e => e.ID == id);
tabpage.Text = ToChatWith.ToString();
dbg("adding tab");
this.tabControl1.TabPages.Add(tabpage);
this.tabControl1.SelectTab(tabpage);
dbg("done adding tab");
}
dbg("leaving");
}
catch (Exception ex)
{
dbg("" + ex);
}
}
Make sure you can find the debugger output in your environment. (Heck, use Console.WriteLine if that helps)
If that doesn't help you diagnose the problem I don't know what will.

Variable outside a try catch block loses value

I am having a little problem. I have a function with a string outside a try-catch-finally block that is changed depending on what happens inside the block. Once that is finished, I want to display it. My problem is that the value that was changed in the block returns to the original value it had. How can I fix this?
string error = "No issues";
try{
error = "Correct";
}catch(Exception ex){
error = "Wrong:" + ex.Message.ToString();
}finally{
// Closes connection
}
MessageBox.Show(error);
It's not clear to me, if the string in question declared outside the method. If you are 100% sure, that a new value is given to the string, the following code will probably do the problem you have:
static void Foo(string s)
{
try
{
s = "OK";
}
catch { }
}
static void Main(string[] args)
{
string temp = "??";
Foo(temp);
Console.WriteLine(temp); //prints ??
Console.ReadLine();
}
as you are passing string by value. If you need to change the value you should either:
make a ref parameter:
static void Foo(ref string s)
and call it
Foo(ref temp);
or return the new value from the method:
static string Foo(string s)
{
try
{
s = "OK";
}
catch { }
return s;
}
and call it:
temp = Foo(temp);
The code you posted will show a message box with the text
Correct
if no exceptions are thrown, otherwise the message
Wrong: (plus the exception's message property)
It will never show the message
No issues
because you overwrite the initial value of error in the first line of your try block.
error will never lose a value (as in I guess become null) given the code you post. Eventually error will go out of scope (e.g. when you exit the method that this code is defined in).
UPDATE
I took your code, created a brand-new WinForms project, double-clicked on Form1 to create a Load event handler, and posted in your code like this:
private void Form1_Load(object sender, EventArgs e)
{
string error = "No issues";
try
{
error = "Correct";
}
catch (Exception ex)
{
error = "Wrong:" + ex.Message.ToString();
}
finally
{
// Closes connection
}
MessageBox.Show(error);
}
The result was a message box that said "Correct".
If that is not what you see in your real code, you are not sharing enough code to reproduce the problem.

ASP.net logging errors that occur on different pages

How would i go about to do this?
protected void Page_Load(object sender, EventArgs e)
{
try
{
doSomething();
}
catch (Exception ex)
{
// Here i would like to know that the page is "Problem.aspx"
// and that it was caused from the doSomething() function
}
}
private void doSomething()
{
logToSomething();
}
Exception object has a stack trace property, which tells you exactly where the error took place.
Also, check out Microsoft Enterprise Library (more specifically the Logging Block).
The logged errors provide a stack trace, among other things, letting you know exactly where the error occurred.
I'm using this little class to log errors, have a look on how i get the page and the function(Stacktrace):
public static class ErrorLog
{
public static void WriteError(Exception ex)
{
try {
string path = "~/error/logs/" + System.DateTime.Now.ToString("dd-MM-yyyy") + ".txt";
if ((!System.IO.File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))) {
System.IO.File.Create(System.Web.HttpContext.Current.Server.MapPath(path)).Close();
}
using (System.IO.StreamWriter w = System.IO.File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path))) {
w.WriteLine(System.Environment.NewLine + "Log Entry : {0}", System.DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));
var page = VirtualPathUtility.GetFileName(HttpContext.Current.Request.Url.AbsolutePath);
w.WriteLine("Error in: " + page);
string message = "Message: " + ex.Message;
w.WriteLine(message);
string stack = "StackTrace: " + ex.StackTrace;
w.WriteLine(stack);
w.WriteLine("__________________________");
w.Flush();
w.Close();
}
} catch (Exception writeLogException) {
try {
WriteError(writeLogException);
} catch (Exception innerEx) {
//ignore
}
}
}
}
It's entirely sufficient for me.
Note: converted from VB.NET, hence untested
You can determine all of that by parsing the Exception message.
Look at your message and use a regex to extract the information you need.
Another option that you may want to look into is ELMAH ( Error Logging Modules and Handlers for ASP.NET ) http://code.google.com/p/elmah/ . I guess it really depends on what your specific needs are.
Use log4net, for logging the error messages. For help look at these article 1 and article 2.
Whatever logging method you use, do something like this.(Hand typed may not compile)
try
{
DoignStuff();
}
catch( Exception ex)
{
Trace.WriteLine( "Exception in <Page Name> while calling DoingStuff() Ex:"+ ex.ToString() );
}
It will start with the page name & method (which is redundant, but makes life easier)
then it will convert the EX to a string which shows call stack and all kinds fo other good stuff and put it in the log file
Note: you have to Type the name of the page in the place of <Page Name> .
Log4Net and Elmah are great to make life easier too.

Resuming execution of code after exception is thrown and caught

How is it possible to resume code execution after an exception is thrown?
For example, take the following code:
namespace ConsoleApplication1
{
public class Test
{
public void s()
{
throw new NotSupportedException();
string #class = "" ;
Console.WriteLine(#class);
Console.ReadLine();
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
}
catch (Exception ex)
{
}
}
}
}
After catching the exception when stepping through, the program will stop running. How can I still carry on execution?
EDIT: What I specifically mean is the line Console.WriteLine(#class); does not seem to be hit, because when I run to it when in debug mode, the program exits from debug mode. I want to run to this line and stop at it.
Thanks
Well, you don't have any code after the catch blocks, so the program would stop running. Not sure what you're trying to do.
The following should be proof that the program doesn't simply "stop" after the catch blocks. It will execute code after the catch blocks if there is code to be executed:
static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
Console.WriteLine("ArgumentException caught!");
}
catch (Exception ex)
{
Console.WriteLine("Exception caught!");
}
Console.WriteLine("I am some code that's running after the exception!");
}
The code will print the appropriate string depending on the exception that was caught. Then, it will print I am some code that's running after the exception! at the end.
UPDATE
In your edit you asked why Console.WriteLine(#class); does not seem to be hit. The reason is that you are explicitly throwing an exception in the very first line of your s() method; anything that follows is ignored. When an exception is encountered, execution stops and the exception is propagated up the call stack until the appropriate handler can handle it (this may be a catch block that corresponds to the try that wraps the statement in question within the same method, or it may be a catch block further up the call-stack. If no appropriate handler is found, the program will terminate with a stacktrace [at least in Java - not sure if the same happens in C#]).
If you want to hit the Console.WriteLine line, then you shouldn't be explicitly throwing an exception at the beginning of the method.
It sounds like you're wanting resumeable exceptions. C# doesn't do resumeable exceptions, and I'm doubtful that CLR supports them.
The purpose of throwing an exception is to abort a function and an entire operation (call stack) if/when something in the call environment (parameters, object state, global state) makes the function's operation impossible or invalid. Passing a zero param to a function that needs to divide a quantity by that param, for example. Division by zero won't produce a meaningful result, and if that's the sole purpose of the function, then the function can't return a meaningful result either. So, throw an exception. This will cause execution to jump to the nearest catch or finally block on the call stack. There is no returning to the function that threw the exception.
If you want to step into your code in the debugger to trace the Console.WriteLine() calls, you need to remove the throw new NotSupportedException() line from your code and recompile.
If you're worried that an exception will be thrown in the method but you want the method to continue, add an error handler inside the method.
class Test
{
public void s()
{
try
{
// Code that may throw an exception
throw new NotSupportedException();
}
catch(Exception ex)
{
// Handle the exception - log?, reset some values?
}
string #class = "" ;
Console.WriteLine(#class);
Console.ReadLine();
}
}
You could also return a bool or some other value to indicate the state.
Disclaimer: I am not suggesting that you actually do this.
You can mimic the old VB style On Error Resume Next with the following code.
public static class ControlFlow
{
public static Exception ResumeOnError(Action action)
{
try
{
action();
return null;
}
catch (Exception caught)
{
return caught;
}
}
}
And then it could be used like the following.
public static void Main()
{
ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); });
ControlFlow.ResumeOnError(() => { Console.WriteLine(); });
ControlFlow.ResumeOnError(() => { Console.ReadLine(); });
}
Some simple code I put together to catch exceptions that are thrown inside a catch block:
try
{
//do code here
}
catch (Exception ex)
{
try { SomeMethod1(); }
catch { }
try { SomeMethod2(); }
catch { }
try { SomeMethod3(); }
catch { }
}
finally
{
//cleanup goes here
}
Execution is still carying on but there is no code after the exception is caught. If you want to repeatedly call s then consider wrapping the try/catch block in a while loop.
The program stops running because there is no following code to be executed in the Main() method! You can add the following line to your code to keep the program running until there is a console input:
Console.ReadLine();
For that code, you can't. If you break the tasks up to smaller chunks, you can resume at the next chunk. But normally it's easier to have a different mechanism than exceptions to report non-fatal errors, such as a callback function which returns whether or not to continue.
You can use the "step-over" feature in debugging to achieve this on a per-run basis.
Instead of thowing the NotSupportedException, you could track that an exception was encountered, use a default value, and throw the exception at the end of the method call:
namespace ConsoleApplication1
{
public class Test
{
public void s()
{
bool exceptionEncountered = false;
if(someConditionNotSupported){//stub condition
exceptionEncountered=true
#class="DefaultValue";
}
Console.WriteLine(#class);
Console.ReadLine();
if(exceptionEncountered){
throw new NotSupportedException();
}
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
}
catch (Exception ex)
{
}
}
}
}
public static void Main()
{
for (int j = 0; j <= 100000; j++)
{
try
{
// TODO: Application logic...
}
catch
{
System.Threading.Thread.Sleep(1000);
}
}
}

Categories