10 Replies - 1813 Views - Last Post: 28 February 2012 - 07:04 AM Rate Topic: -----

#1 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 3
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Thread/Task exception handling

Posted 27 February 2012 - 05:56 AM

Afternoon,

Im a little confused about the subject. As far as i was aware, if i created a task, caught an exception and then rethrew it, it wouldnt be caught by the main GUI thread. If this is so, is it the same for Tasks?

How do/would you notify the main GUI thread that an exception has occured in a task? Do i need to create an event and get the GUI thread subscribed to it?

Thanks in advance.
Is This A Good Question/Topic? 0
  • +

Replies To: Thread/Task exception handling

#2 Momerath  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 810
  • View blog
  • Posts: 1,952
  • Joined: 04-October 09

Re: Thread/Task exception handling

Posted 27 February 2012 - 07:08 AM

http://msdn.microsof...y/dd997415.aspx
Was This Post Helpful? 1
  • +
  • -

#3 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 3
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Thread/Task exception handling

Posted 27 February 2012 - 07:12 AM

its the

Quote

joining thread
part which i dont understood. Could you elaborate on it please.
Was This Post Helpful? 0
  • +
  • -

#4 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 916
  • View blog
  • Posts: 921
  • Joined: 30-September 10

Re: Thread/Task exception handling

Posted 27 February 2012 - 11:59 AM

Hi,

Say thread A joins with thread B, thus making thread A the 'joining thread'. All that basically means is that thread A will wait/block until thread B has completed.

In the context of .NET Tasks and exceptions thrown from within them, it is saying that any exception thrown from within the task will be propagated to the thread that is explicitly waiting for that task to complete (i.e. the 'joining thread'). The obvious way of making a thread explicitly wait for a task to complete is to call the Wait() method on the task.

However, explicitly waiting for a task to complete isn't the only way of catching and handling exceptions thrown from a task, as Momerath's link explains.
Was This Post Helpful? 1
  • +
  • -

#5 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 1959
  • View blog
  • Posts: 8,700
  • Joined: 29-May 08

Re: Thread/Task exception handling

Posted 27 February 2012 - 12:14 PM

Tasks don't throw exceptions. They capture and preserve them so they can be examine at late time.

MSDN: Task
Was This Post Helpful? 1
  • +
  • -

#6 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 3
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Thread/Task exception handling

Posted 27 February 2012 - 01:56 PM

so to summarise, i can do one of the following:
  • Call Task.Wait() after i have created my task(s)
  • Specifying the ContinueWith. Is this run on the Threadpool or the thread used to create the threads?


so if i had a block of code similar to the following (Im reinstalling VS atm so this is prob full of errors)and was running it with a task now, there is no point in having the try catch in there, and instead i should just use either of the two options listed above?

public void PerformComputation(int x, int y)
{
  try
  { 
    byte temp = x *y;
  }
  Catch (ArgumentOutofRangeException ex)
  {
    ....
  }
}


Thanks guys

This post has been edited by scolty: 27 February 2012 - 01:56 PM

Was This Post Helpful? 0
  • +
  • -

#7 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 916
  • View blog
  • Posts: 921
  • Joined: 30-September 10

Re: Thread/Task exception handling

Posted 27 February 2012 - 02:56 PM

Generally speaking, those are your two main options to catch an exception that was thrown from in a task, yes (excluding registering with the UnobservedTaskException event).


The delegate passed to ContinueWith will be run on a thread pool thread by default. However, you can specify exactly what thread it should execute on by passing it a TaskScheduler instance that was captured in the context of the thread you want the delegate to execute on.

Also, if you pass the TaskContinuationOptions.LongRunning option to ContinueWith(), it will be run on a non thread pool thread.


If you are talking about running that entire method in a task, you might still sometimes want to catch exceptions like you have there. If you can handle the exception that was thrown safely and reliably there and then inside the task, you may not want to let it propagate up out of the task and run the risk of bringing down your application, for example. Or, if you want to perform some basic processing of the exception there and then, you may want to catch the exception in the task, perform the processing, and then re-throw the exception for handling via the methods you described.

Generally, you probably will want to just let the exceptions propagate up, and handle it using the one of the two general methods you described.
Was This Post Helpful? 1
  • +
  • -

#8 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 3
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Thread/Task exception handling

Posted 27 February 2012 - 03:05 PM

ok cool, i was under the impression i might as well have not bothered writting the "normal" exception handling code as it wouldnt be used. Glad to see i was mistaken!

Thanks for clarifying that.
Was This Post Helpful? 0
  • +
  • -

#9 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 1959
  • View blog
  • Posts: 8,700
  • Joined: 29-May 08

Re: Thread/Task exception handling

Posted 27 February 2012 - 03:13 PM

The exception inside a Task isn't raised when it happens, because it'll make the code synchronous and Task are/were designed for concurrency.

The task object the is created has the property
.IsFaulted


which you can check to see it has an exception.

Task Tutorial (vb.net)

This post has been edited by AdamSpeight2008: 27 February 2012 - 03:15 PM

Was This Post Helpful? 1
  • +
  • -

#10 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 916
  • View blog
  • Posts: 921
  • Joined: 30-September 10

Re: Thread/Task exception handling

Posted 27 February 2012 - 04:20 PM

Also note that in the same way that calling Wait() on a task causes the AggregateException to be propagated, accessing the Result property of a task will too.

EDIT: As will calling WaitAny() or WaitAll().

This post has been edited by CodingSup3rnatur@l-360: 27 February 2012 - 04:24 PM

Was This Post Helpful? 1
  • +
  • -

#11 scolty  Icon User is offline

  • D.I.C Regular

Reputation: 3
  • View blog
  • Posts: 259
  • Joined: 27-April 11

Re: Thread/Task exception handling

Posted 28 February 2012 - 07:04 AM

Alright, ive made a small program up and messed with it a little. If i leave the try/catch block in the taskbody() method, they catch the exception. Having them there also allows the UI thread to start executing UIThreadDelayer().

BUT

If i place the try catch block after the creation of the task and have tsk.Wait(); in there, the UI thread waits. Im therefore a little confused as to why i would bother catching the aggregate exception when i could just catch the exception in the code especially since i want the UI thread to be available to update the GUI and i want to use a for loop to execute several tasks.

Im assuming since this doesnt seem to work that what im doing is another amazing example of poor programming practice??

Thanks for your help guys




using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace Exception_handling_with_Tasks
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Create new task.
            Task tsk = Task.Factory.StartNew(() =>
                {
                    TaskBody();
                });
            try
            {
                tsk.Wait();
            }
            catch (AggregateException ex)
            {
                foreach (Exception einner in ex.InnerExceptions)
                {
                    MessageBox.Show(einner.Message.ToString());
                }
            }
            
            
            //Call a method to keep UI thread busy.
            UIThreadDelayer();
        }

        public void UIThreadDelayer()
        {
            for (int i = 0; i < 20; i++)
            {
                textBox1.Text += i.ToString();
            }
        }

        public void TaskBody()
        {
            for(int i = 0;i<20;i++)
            {
                //try
                {
                    if (i == 5)
                    {
                        throw new SyntaxErrorException();
                    }

                    if (i == 10)
                    {
                        throw new OutOfMemoryException();
                    }
                }
                /*catch (SyntaxErrorException ex1)
                {
                    MessageBox.Show(ex1.Message.ToString());
                }

                catch (OutOfMemoryException ex2)
                {
                    MessageBox.Show(ex2.Message.ToString());
                }*/
            }
        }
    }
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1