Rediger

Del via


<ThrowUnobservedTaskExceptions> Element

Specifies whether unhandled task exceptions should terminate a running process.

<configuration>
  <runtime>
    <ThrowUnobservedTaskExceptions>

Syntax

<ThrowUnobservedTaskExceptions  
   enabled="true|false"/>  

Attributes and Elements

The following sections describe attributes, child elements, and parent elements.

Attributes

Attribute Description
enabled Required attribute.

Specifies whether unhandled task exceptions should terminate the running process.

enabled Attribute

Value Description
false Does not terminate the running process for an unhandled task exception. This is the default.
true Terminates the running process for an unhandled task exception.

Child Elements

None.

Parent Elements

Element Description
configuration The root element in every configuration file used by the common language runtime and .NET Framework applications.
runtime Contains information about runtime initialization options.

Remarks

If an exception that is associated with a Task has not been observed, there is no Wait operation, the parent is not attached, and the Task.Exception property was not read the task exception is considered to be unobserved.

In the .NET Framework 4, by default, if a Task that has an unobserved exception is garbage collected, the finalizer throws an exception and terminates the process. The termination of the process is determined by the timing of garbage collection and finalization.

To make it easier for developers to write asynchronous code based on tasks, the .NET Framework 4.5 changes this default behavior for unobserved exceptions. Unobserved exceptions still cause the UnobservedTaskException event to be raised, but by default, the process does not terminate. Instead, the exception is ignored after the event is raised, regardless of whether an event handler observes the exception.

In .NET Framework 4.5, you can use the <ThrowUnobservedTaskExceptions> element in an application configuration file to enable the .NET Framework 4 behavior of throwing an exception.

You can also specify the exception behavior in one of the following ways:

  • By setting the environment variable COMPlus_ThrowUnobservedTaskExceptions (set COMPlus_ThrowUnobservedTaskExceptions=1).

  • By setting the registry DWORD value ThrowUnobservedTaskExceptions = 1 in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework key.

Example 1

The following example shows how to enable the throwing of exceptions in tasks by using an application configuration file.

<configuration>
    <runtime>
        <ThrowUnobservedTaskExceptions enabled="true"/>
    </runtime>
</configuration>  

Example 2

The following example demonstrates how an unobserved exception is thrown from a task. The code must be run as a released program to work correctly.

using System;
using System.Threading;
using System.Collections.Generic;
using System.Threading.Tasks;

//Use the following config settings to enable the throwing of unobserved exceptions.
//    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
//    <ThrowUnobservedTaskExceptions enabled="true"/>

public class Example
{
    static void Main()
    {
        Task.Run(() => { throw new InvalidOperationException("test"); });
        while (true)
        {
            Thread.Sleep(100);
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }
}
Imports System.Threading
Imports System.Threading.Tasks

'Use the following config settings to enable the throwing of unobserved exceptions.
'    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
'    <ThrowUnobservedTaskExceptions enabled="true"/>

Public Class Example
    Shared Sub Main()
        Task.Run(Sub() Throw New InvalidOperationException("test"))
        Do
            Thread.Sleep(100)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        Loop
    End Sub
End Class

See also