TaskExtensions.Unwrap 方法

定义

重载

Unwrap(Task<Task>)

创建一个表示 Task 的异步操作的代理 Task<Task> (C#) or Task (Of Task) (Visual Basic)。

Unwrap<TResult>(Task<Task<TResult>>)

创建一个表示 Task 的异步操作的代理 Task<Task<T>> (C#) or Task (Of Task(Of T)) (Visual Basic)。

Unwrap(Task<Task>)

Source:
TaskExtensions.cs
Source:
TaskExtensions.cs
Source:
TaskExtensions.cs

创建一个表示 Task 的异步操作的代理 Task<Task> (C#) or Task (Of Task) (Visual Basic)。

public:
[System::Runtime::CompilerServices::Extension]
 static System::Threading::Tasks::Task ^ Unwrap(System::Threading::Tasks::Task<System::Threading::Tasks::Task ^> ^ task);
public static System.Threading.Tasks.Task Unwrap (this System.Threading.Tasks.Task<System.Threading.Tasks.Task> task);
static member Unwrap : System.Threading.Tasks.Task<System.Threading.Tasks.Task> -> System.Threading.Tasks.Task
<Extension()>
Public Function Unwrap (task As Task(Of Task)) As Task

参数

task
Task<Task>

要解包的 Task<Task> (C#) 或者 Task (Of Task) (Visual Basic)。

返回

表示所提供的 System.Threading.Tasks.Task(Of Task) 的异步操作的 Task。

例外

task 参数为 null 时引发的异常。

示例

以下示例演示如何解包任务:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

class UnWrapDemo
{
     // Demonstrated features:
        //		Task.Unwrap()
        // 		Task.Factory.StartNew()
        //		Task.ContinueWith()
        // Expected results:
        // 		Indicates that continuation chains can be set up virtually instantaneously using Unwrap(), and then left to run on their own.
        //      The results of the RemoteIncrement(0) chain and the RemoteIncrement(4) chain may be intermixed with each other.
        //		The results of the sequence that starts with RemoteIncrement(4) are in strict order.
        // Documentation:
        //		http://msdn.microsoft.com/library/dd781129(VS.100).aspx
        // More information:
        //		http://blogs.msdn.com/pfxteam/archive/2009/11/04/9917581.aspx
        // Other notes:
        //		The combination of Task<T>, ContinueWith() and Unwrap() can be particularly useful for setting up a chain of long-running
        //      tasks where each task uses the results of its predecessor.
        static void Main()
        {
            // Invoking individual tasks is straightforward
            Task<int> t1 = RemoteIncrement(0);
            Console.WriteLine("Started RemoteIncrement(0)");

            // Chain together the results of (simulated) remote operations.
            // The use of Unwrap() instead of .Result below prevents this thread from blocking while setting up this continuation chain.
            Task<int> t2 = RemoteIncrement(4)
                .ContinueWith(t => RemoteIncrement(t.Result))			// RemoteIncrement() returns Task<int> so no unwrapping is needed for the first continuation.
                .Unwrap().ContinueWith(t => RemoteIncrement(t.Result))	// ContinueWith() returns Task<Task<int>>. Therefore unwrapping is needed.
                .Unwrap().ContinueWith(t => RemoteIncrement(t.Result))	// and on it goes...
                .Unwrap();
            Console.WriteLine("Started RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)");

            try
            {
                t1.Wait();
                Console.WriteLine("Finished RemoteIncrement(0)\n");

                t2.Wait();
                Console.WriteLine("Finished RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)");
            }
            catch (AggregateException e)
            {
                Console.WriteLine("A task has thrown the following (unexpected) exception:\n{0}", e);
            }
        }
        // This method represents a remote API.
        static Task<int> RemoteIncrement(int n)
        {
            return Task<int>.Factory.StartNew(
                (obj) =>
                {
                    // Simulate a slow operation
                    Thread.Sleep(1 * 1000);

                    int x = (int)obj;
                    Console.WriteLine("Thread={0}, Next={1}", Thread.CurrentThread.ManagedThreadId, ++x);
                    return x;
                },
                n);
        }
}
Imports System.Threading
Imports System.Threading.Tasks

Module UnwrapDemo
    ' Demonstrated features:
    '   Task.Unwrap()
    '    Task.Factory.StartNew()
    '   Task.ContinueWith()
    ' Expected results:
    ' 	Indicates that continuation chains can be set up virtually instantaneously using Unwrap(), and then left to run on their own.
    '   The results of the RemoteIncrement(0) chain and the RemoteIncrement(4) chain may be intermixed with each other.
    '   The results of the sequence that starts with RemoteIncrement(4) are in strict order.
    ' Documentation:
    '   http://msdn.microsoft.com/library/dd781129(VS.100).aspx
    ' More information:
    '   http://blogs.msdn.com/pfxteam/archive/2009/11/04/9917581.aspx
    ' Other notes:
    '   The combination of Task<T>, ContinueWith() and Unwrap() can be particularly useful for setting up a chain of long-running
    '   tasks where each task uses the results of its predecessor.

    Sub Main()
        ' Invoking individual tasks is straightforward
        Dim t1 As Task(Of Integer) = RemoteIncrement(0)
        Console.WriteLine("Started RemoteIncrement(0)")

        ' Chain together the results of (simulated) remote operations.
        ' The use of Unwrap() instead of .Result below prevents this thread from blocking while setting up this continuation chain.
        ' RemoteIncrement() returns Task<int> so no unwrapping is needed for the first continuation.
        ' ContinueWith() here returns Task<Task<int>>. Therefore unwrapping is needed.
        ' and on it goes...
        Dim t2 As Task(Of Integer) = RemoteIncrement(4).ContinueWith(Function(t) RemoteIncrement(t.Result)).Unwrap().ContinueWith(Function(t) RemoteIncrement(t.Result)).Unwrap().ContinueWith(Function(t) RemoteIncrement(t.Result)).Unwrap()
        Console.WriteLine("Started RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)")

        Try
            t1.Wait()
            Console.WriteLine("Finished RemoteIncrement(0)" & vbLf)

            t2.Wait()
            Console.WriteLine("Finished RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)")
        Catch e As AggregateException
            Console.WriteLine("A task has thrown the following (unexpected) exception:" & vbLf & "{0}", e)

        End Try
    End Sub

    ' This method represents a remote API.
    Function RemoteIncrement(ByVal n As Integer) As Task(Of Integer)
        Return Task(Of Integer).Factory.StartNew(Function(obj)
                                                     ' Simulate a slow operation
                                                     Thread.Sleep(1 * 1000)

                                                     Dim x As Integer = CInt(obj)
                                                     Console.WriteLine("Thread={0}, Next={1}", Thread.CurrentThread.ManagedThreadId, System.Threading.Interlocked.Increment(x))
                                                     Return x
                                                 End Function, n)
    End Function


End Module

注解

能够从 Task<TResult>返回 Task 通常很有用,其中内部 Task 表示作为外部 Task<TResult>的一部分完成的工作。 但是,这样做会导致 Task<Task> (C#) 或 Task (Of Task) (Visual Basic) ,如果不仔细处理,可能会产生意外行为。 解包通过创建表示此类任务的整个异步操作的代理任务来解决此问题。

另请参阅

适用于

Unwrap<TResult>(Task<Task<TResult>>)

Source:
TaskExtensions.cs
Source:
TaskExtensions.cs
Source:
TaskExtensions.cs

创建一个表示 Task 的异步操作的代理 Task<Task<T>> (C#) or Task (Of Task(Of T)) (Visual Basic)。

public:
generic <typename TResult>
[System::Runtime::CompilerServices::Extension]
 static System::Threading::Tasks::Task<TResult> ^ Unwrap(System::Threading::Tasks::Task<System::Threading::Tasks::Task<TResult> ^> ^ task);
public static System.Threading.Tasks.Task<TResult> Unwrap<TResult> (this System.Threading.Tasks.Task<System.Threading.Tasks.Task<TResult>> task);
static member Unwrap : System.Threading.Tasks.Task<System.Threading.Tasks.Task<'Result>> -> System.Threading.Tasks.Task<'Result>
<Extension()>
Public Function Unwrap(Of TResult) (task As Task(Of Task(Of TResult))) As Task(Of TResult)

类型参数

TResult

任务结果的类型。

参数

task
Task<Task<TResult>>

要解包的 Task<Task<T>> (C#) 或者 Task (Of Task(Of T)) (Visual Basic)。

返回

一个 Task 它表示所提供的 Task<Task<T>> (C#) 或 Task (Of Task(Of T)) (Visual Basic) 的异步运算。

例外

task 参数为 null 时引发的异常。

注解

通常,能够从 Task返回 Task ,其中内部 Task 表示作为外部 Task的一部分完成的工作。 但是,这样做会导致 Task<Task<T>> (C#) 或 Task (Of Task(Of T)) (Visual Basic) ,如果不仔细处理,可能会产生意外行为。 Unwrap 通过创建表示此类 Task<Task<T>> (C#) 或 Task (Of Task(Of T)) (Visual Basic) 的整个异步操作的代理Task<TResult>来解决此问题。

另请参阅

适用于