TaskExtensions.Unwrap 方法

定義

多載

Unwrap(Task<Task>)

建立 Proxy Task,表示 Task<Task> (C#) 或 Task (Of Task) (Visual Basic) 的非同步作業。

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

建立 Proxy Task,表示 Task<Task<T>> (C#) 或 Task (Of Task(Of T)) (Visual Basic) 的非同步作業。

Unwrap(Task<Task>)

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

建立 Proxy Task,表示 Task<Task> (C#) 或 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 引數為 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 Task<TResult> 通常很有用,其中內部 Task 代表做為外部 Task<TResult> 完成的工作。 不過,這樣做會導致 Task<Task> (C#) 或 Task (Of Task) (Visual Basic) ,如果沒有小心處理,可能會產生非預期的行為。 解除包裝可藉由建立代表這類工作之整個非同步作業的 Proxy 工作來解決此問題。

另請參閱

適用於

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

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

建立 Proxy Task,表示 Task<Task<T>> (C#) 或 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) ,如果沒有小心處理,可能會產生非預期的行為。 解除包裝可藉由建立 Task<TResult> Proxy 來代表這類 Task<Task<T>> (C#) 的整個非同步作業,或 Task (Of Task(Of T)) (Visual Basic) 來解決此問題。

另請參閱

適用於