. Net (C #) TPL: the task is not aware of exceptions and taskscheduler. unobservedtaskexception events.

Source: Internet
Author: User

When you throw an exception in a task execution, for example:

Task. Factory. startnew () =>

{

Throw new exception ();

});

Run this method and no exception is thrown.

 

In fact, at this time, the task exception is in the imperceptible state. This imperceptible state exception will be thrown in the terminator execution thread during garbage collection.

To induce this exception, we can use GC. Collect to force garbage collection to cause the terminator to process the thread. At this time, the imperceptible exception of the task will be thrown.

// Throw an exception in the task

Task. Factory. startnew () =>

{

Throw new exception ();

});

 

// Make sure the task is completed

Thread. Sleep (100 );

// Force the spam to receive

GC. Collect ();

// Wait for the terminator to process

GC. waitforpendingfinalizers ();

 

OK, an exception is thrown, the program crashes, and the output is as follows:

Unhandled exception: system. aggresponexception: a task's exception (s) were not

Bserved either by waiting on the task or accessing its exception property. As

Result, the unobserved exception was rethrown by the finalizer thread. ---> sys

Em. Exception: exception of Type 'System. exception' was thrown.

At mgen. program. <main> B _ 0 () in E: \ Users \ mgen \ Documents \ Visual Studio 2010 \ P

Ojects \ mgen \ Program. CS: Line 19

At system. Threading. Tasks. task. innerinvoke ()

At system. Threading. Tasks. task. Execute ()

--- End of inner exception stack trace ---

At system. Threading. Tasks. taskexceptionholder. Finalize ()

 

You can detect exceptions of a task by calling task. Wait/waitall, referencing the task <t>. Result attribute, or referencing the task. Exception attribute in the simplest way. For example:

 

Manually capture aggresponexception through task. Wait:

Try

{

Task. waitall (

Task. Factory. startnew () =>

{

Throw new exception ();

}));

}

Catch (aggresponexception)

{}

 

// Make sure the task is completed

Thread. Sleep (100 );

// Force the spam to receive

GC. Collect ();

// Wait for the terminator to process

GC. waitforpendingfinalizers ();

In this way, no exception is thrown (even if the terminator thread has ended ).

 

Of course, the simplest thing is to directly reference the task. Exception attribute:

Note that task. continuewith is used here to avoid directly referencing task variables, so that garbage collection can process this task object!

// Use task. continuewith to avoid directly referencing task variables, so that garbage collection can process this task object!

Task. Factory. startnew () =>

{

Throw new exception ();

}). Continuewith (t => {var exp = T. exception ;});

 

// Make sure the task is completed

Thread. Sleep (100 );

// Force the spam to receive

GC. Collect ();

// Wait for the terminator to process

GC. waitforpendingfinalizers ();

No exception is thrown.

 

In addition, you can use taskcontinuationoptions. onlyonfaulted to reference the exception attribute only when an exception occurs (that is, when exception is null, you do not need to reference it again). Code:

Task. Factory. startnew () =>

{

Throw new exception ();

}). Continuewith (t => {var exp = T. exception;}, taskcontinuationoptions. onlyonfaulted );

 

The last is the taskscheduler. unobservedtaskexception event, which is the last method that can be noticed before all imperceptible exceptions are thrown. The unobservedtaskexceptioneventargs. setobserved method is used to mark an exception as imperceptible.

 

Code:

Taskschedexception. unobservedtaskexception + = (S, e) =>

{

// Set all imperceptible exceptions to be noticed

E. setobserved ();

};

 

Task. Factory. startnew () =>

{

Throw new exception ();

});

 

// Make sure the task is completed

Thread. Sleep (100 );

// Force the spam to receive

GC. Collect ();

// Wait for the terminator to process

GC. waitforpendingfinalizers ();

OK. No exception is thrown.

 

 

Note that this phenomenon has changed after. Net 4.5. refer:

. Net 4.5 (C #): update of tasks with imperceptible exceptions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.