TaskExtensions.Unwrap 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
多載
Unwrap(Task<Task>) |
建立 Proxy Task,表示 |
Unwrap<TResult>(Task<Task<TResult>>) |
建立 Proxy Task,表示 |
Unwrap(Task<Task>)
建立 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
參數
傳回
工作,表示提供之 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>>)
建立 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<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) 來解決此問題。