Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Sie können eine Aufgabe aus einer Methode zurückgeben und anschließend warten oder von dieser Aufgabe aus fortfahren, wie im folgenden Beispiel gezeigt:
static Task<string> DoWorkAsync() => Task<string>.Factory.StartNew(() =>
{
//...
return "Work completed.";
});
static void StartTask()
{
Task<string> t = DoWorkAsync();
t.Wait();
Console.WriteLine(t.Result);
}
Shared Function DoWorkAsync() As Task(Of String)
Return Task(Of String).Run(Function()
'...
Return "Work completed."
End Function)
End Function
Shared Sub StartTask()
Dim t As Task(Of String) = DoWorkAsync()
t.Wait()
Console.WriteLine(t.Result)
End Sub
Im vorherigen Beispiel ist die Result Eigenschaft vom Typ string
(String
in Visual Basic).
In einigen Szenarien möchten Sie jedoch möglicherweise eine Aufgabe innerhalb einer anderen Aufgabe erstellen und dann die geschachtelte Aufgabe zurückgeben. In diesem Fall ist TResult
der einschließenden Aufgabe selbst eine Aufgabe. Im folgenden Beispiel ist die Eigenschaft Result ein Task<Task<string>>
in C# oder ein Task(Of Task(Of String))
in Visual Basic.
// Note the type of t and t2.
Task<Task<string>> t = Task.Factory.StartNew(DoWorkAsync);
Task<Task<string>> t2 = DoWorkAsync().ContinueWith((s) => DoMoreWorkAsync());
// Outputs: System.Threading.Tasks.Task`1[System.String]
Console.WriteLine(t.Result);
' Note the type of t and t2.
Dim t As Task(Of Task(Of String)) = Task.Run(Function() DoWorkAsync())
Dim t2 As Task(Of Task(Of String)) = DoWorkAsync().ContinueWith(Function(s) DoMoreWorkAsync())
' Outputs: System.Threading.Tasks.Task`1[System.String]
Console.WriteLine(t.Result)
Obwohl es möglich ist, Code zum Entpacken der äußeren Aufgabe und Abrufen der ursprünglichen Aufgabe und seiner Result Eigenschaft zu schreiben, ist dieser Code nicht einfach zu schreiben, da Sie Ausnahmen und auch Abbruchanforderungen behandeln müssen. In diesem Fall wird empfohlen, eine der Unwrap Erweiterungsmethoden zu verwenden, wie im folgenden Beispiel gezeigt.
// Unwrap the inner task.
Task<string> t3 = DoWorkAsync().ContinueWith((s) => DoMoreWorkAsync()).Unwrap();
// Outputs "More work completed."
Console.WriteLine(t.Result);
' Unwrap the inner task.
Dim t3 As Task(Of String) = DoWorkAsync().ContinueWith(Function(s) DoMoreWorkAsync()).Unwrap()
' Outputs "More work completed."
Console.WriteLine(t.Result)
Die Unwrap Methoden können verwendet werden, um eine Task<Task>
oder Task<Task<TResult>>
(Task(Of Task)
oder Task(Of Task(Of TResult))
in Visual Basic) in ein Task
oder Task<TResult>
(Task(Of TResult)
in Visual Basic) zu transformieren. Die neue Aufgabe stellt die geschachtelte innere Aufgabe vollständig dar und enthält den Abbruchstatus sowie alle Ausnahmen.
Beispiel
Im folgenden Beispiel wird die Verwendung der Unwrap Erweiterungsmethoden veranschaulicht.
namespace Unwrap
{
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// An arbitrary threshold value.
byte threshold = 0x40;
// data is a Task<byte[]>
Task<byte[]> data = Task<byte[]>.Factory.StartNew(GetData);
// We want to return a task so that we can
// continue from it later in the program.
// Without Unwrap: stepTwo is a Task<Task<byte[]>>
// With Unwrap: stepTwo is a Task<byte[]>
Task<byte> stepTwo = data.ContinueWith((antecedent) =>
{
return Task<byte>.Factory.StartNew(() => Compute(antecedent.Result));
})
.Unwrap();
// Without Unwrap: antecedent.Result = Task<byte>
// and the following method will not compile.
// With Unwrap: antecedent.Result = byte and
// we can work directly with the result of the Compute method.
Task<Task> lastStep = stepTwo.ContinueWith((antecedent) =>
{
if (antecedent.Result >= threshold)
{
return Task.Factory.StartNew(() =>
Console.WriteLine($"Program complete. Final = 0x{stepTwo.Result:x} threshold = 0x{threshold:x}"));
}
else
{
return DoSomeOtherAsynchronousWork(stepTwo.Result, threshold);
}
});
lastStep.Wait();
Console.WriteLine("Press any key");
Console.ReadKey();
}
#region Dummy_Methods
private static byte[] GetData()
{
Random rand = new();
byte[] bytes = new byte[64];
rand.NextBytes(bytes);
return bytes;
}
static Task DoSomeOtherAsynchronousWork(int i, byte b2)
{
return Task.Factory.StartNew(() =>
{
Thread.SpinWait(500000);
Console.WriteLine("Doing more work. Value was <= threshold");
});
}
static byte Compute(byte[] data)
{
byte final = 0;
foreach (byte item in data)
{
final ^= item;
Console.WriteLine($"{final:x}");
}
Console.WriteLine("Done computing");
return final;
}
#endregion
}
}
'How to: Unwrap a Task
Imports System.Threading
Imports System.Threading.Tasks
Module UnwrapATask2
Sub Main()
' An arbitrary threshold value.
Dim threshold As Byte = &H40
' myData is a Task(Of Byte())
Dim myData As Task(Of Byte()) = Task.Factory.StartNew(Function()
Return GetData()
End Function)
' We want to return a task so that we can
' continue from it later in the program.
' Without Unwrap: stepTwo is a Task(Of Task(Of Byte))
' With Unwrap: stepTwo is a Task(Of Byte)
Dim stepTwo = myData.ContinueWith(Function(antecedent)
Return Task.Factory.StartNew(Function()
Return Compute(antecedent.Result)
End Function)
End Function).Unwrap()
Dim lastStep = stepTwo.ContinueWith(Function(antecedent)
Console.WriteLine("Result = {0}", antecedent.Result)
If antecedent.Result >= threshold Then
Return Task.Factory.StartNew(Sub()
Console.WriteLine("Program complete. Final = &H{1:x} threshold = &H{1:x}",
stepTwo.Result, threshold)
End Sub)
Else
Return DoSomeOtherAsynchronousWork(stepTwo.Result, threshold)
End If
End Function)
Try
lastStep.Wait()
Catch ae As AggregateException
For Each ex As Exception In ae.InnerExceptions
Console.WriteLine(ex.Message & ex.StackTrace & ex.GetBaseException.ToString())
Next
End Try
Console.WriteLine("Press any key")
Console.ReadKey()
End Sub
#Region "Dummy_Methods"
Function GetData() As Byte()
Dim rand As Random = New Random()
Dim bytes(64) As Byte
rand.NextBytes(bytes)
Return bytes
End Function
Function DoSomeOtherAsynchronousWork(ByVal i As Integer, ByVal b2 As Byte) As Task
Return Task.Factory.StartNew(Sub()
Thread.SpinWait(500000)
Console.WriteLine("Doing more work. Value was <= threshold.")
End Sub)
End Function
Function Compute(ByVal d As Byte()) As Byte
Dim final As Byte = 0
For Each item As Byte In d
final = final Xor item
Console.WriteLine("{0:x}", final)
Next
Console.WriteLine("Done computing")
Return final
End Function
#End Region
End Module