以工作為基礎的非同步模式 (TAP)Task-based asynchronous pattern (TAP)

工作式非同步模式 (TAP) 是以 System.Threading.Tasks.Task 命名空間中的 System.Threading.Tasks.Task<TResult>System.Threading.Tasks 類型為基礎,這兩種類別用於表示任意非同步作業。The Task-based Asynchronous Pattern (TAP) is based on the System.Threading.Tasks.Task and System.Threading.Tasks.Task<TResult> types in the System.Threading.Tasks namespace, which are used to represent arbitrary asynchronous operations. TAP 是進行新的開發工作時,建議使用的非同步設計模式。TAP is the recommended asynchronous design pattern for new development.

命名、參數和傳回型別Naming, parameters, and return types

TAP 使用單一方法表示非同步作業的啟始和完成。TAP uses a single method to represent the initiation and completion of an asynchronous operation. 這與非同步程式設計模型 (APM 或 IAsyncResult) 模式和事件架構非同步模式 (EAP) 形成對比。This contrasts with both the Asynchronous Programming Model (APM or IAsyncResult) pattern and the Event-based Asynchronous Pattern (EAP). APM 要求 BeginEnd 方法。APM requires Begin and End methods. EAP 需要一個具有 Async 尾碼的方法,也需要一或多個事件、事件處理常式委派類型,以及 EventArg 衍生型別。EAP requires a method that has the Async suffix and also requires one or more events, event handler delegate types, and EventArg-derived types. TAP 中的非同步方法會在傳回可等候型別之方法的作業名稱後面包括 Async 尾碼,例如 TaskTask<TResult>ValueTaskValueTask<TResult>Asynchronous methods in TAP include the Async suffix after the operation name for methods that return awaitable types, such as Task, Task<TResult>, ValueTask, and ValueTask<TResult>. 例如,GetAsync 表示傳回 Task<String> 的非同步 Get 作業。For example, an asynchronous Get operation that returns a Task<String> can be named GetAsync. 如果您將 TAP 方法加入至已包含具有 Async 尾碼之 EAP 方法名稱的類別,請改用 TaskAsync 尾碼。If you're adding a TAP method to a class that already contains an EAP method name with the Async suffix, use the suffix TaskAsync instead. 例如,如果類別已經有 GetAsync 方法,請使用 GetTaskAsync 這個名稱。For example, if the class already has a GetAsync method, use the name GetTaskAsync. 如果方法啟動非同步作業但不傳回可等候型別,則其名稱應以 BeginStart 或其他動詞開頭,以表明此方法不傳回或擲回作業的結果。If a method starts an asynchronous operation but does not return an awaitable type, its name should start with Begin, Start, or some other verb to suggest that this method does not return or throw the result of the operation.  

TAP 方法會傳回 System.Threading.Tasks.TaskSystem.Threading.Tasks.Task<TResult>,取決於對應的同步方法傳回 void 或 TResult 類型。A TAP method returns either a System.Threading.Tasks.Task or a System.Threading.Tasks.Task<TResult>, based on whether the corresponding synchronous method returns void or a type TResult.

TAP 方法的參數應該與其同步對應項目的參數相符,並且應該以相同順序提供。The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. 不過,outref 參數不受限於這項規則,因此應完全避免使用。However, out and ref parameters are exempt from this rule and should be avoided entirely. 所有可能會透過 outref 參數傳回的資料,都應該改成做為 TResult 所傳回 Task<TResult> 的一部分傳回,而且應使用 Tuple 或自訂資料結構來容納多個值。Any data that would have been returned through an out or ref parameter should instead be returned as part of the TResult returned by Task<TResult>, and should use a tuple or a custom data structure to accommodate multiple values. 即使 TAP 方法的同步對應項目沒有提供 CancellationToken 參數,您也應該考慮新增一個。You should also consider adding a CancellationToken parameter even if the TAP method's synchronous counterpart does not offer one.

專門用於建立、管理或組合工作的方法 (其中方法的非同步用意以方法名稱或方法所屬的類型名稱清楚表示) 不需要遵循這個命名模式,這類方法通常稱為「組合器」 。Methods that are devoted exclusively to the creation, manipulation, or combination of tasks (where the asynchronous intent of the method is clear in the method name or in the name of the type to which the method belongs) need not follow this naming pattern; such methods are often referred to as combinators. 組合器的範例包括 WhenAllWhenAny,並且將在使用以工作為基礎的非同步模式文件的使用內建工作式組合器一節中加以討論。Examples of combinators include WhenAll and WhenAny, and are discussed in the Using the Built-in Task-based Combinators section of the article Consuming the Task-based Asynchronous Pattern.

如需說明 TAP 語法與舊有非同步程式設計模式 (例如非同步程式設計模型 (APM) 和事件式非同步模式 (EAP)) 的語法之間差異的範例,請參閱非同步程式設計模式For examples of how the TAP syntax differs from the syntax used in legacy asynchronous programming patterns such as the Asynchronous Programming Model (APM) and the Event-based Asynchronous Pattern (EAP), see Asynchronous Programming Patterns.

啟始非同步作業Initiating an asynchronous operation

以 TAP 為基礎的非同步方法可以先同步處理少量供作,例如驗證引數和啟始非同步作業,再傳回產生的工作。An asynchronous method that is based on TAP can do a small amount of work synchronously, such as validating arguments and initiating the asynchronous operation, before it returns the resulting task. 同步工作量應盡量維持最少,這樣非同步方法才可以快速傳回。Synchronous work should be kept to the minimum so the asynchronous method can return quickly. 快速傳回的原因如下:Reasons for a quick return include the following:

  • 非同步方法可能是從使用者介面 (UI) 執行緒叫用,而任何長時間執行的同步工作都可能影響應用程式的回應。Asynchronous methods may be invoked from user interface (UI) threads, and any long-running synchronous work could harm the responsiveness of the application.

  • 可能有多個非同步方法同時啟動。Multiple asynchronous methods may be launched concurrently. 因此,在非同步方法的同步處理部分中,所有長時間執行的工作都可能延遲啟始其他非同步作業,因而降低並行的優勢。Therefore, any long-running work in the synchronous portion of an asynchronous method could delay the initiation of other asynchronous operations, thereby decreasing the benefits of concurrency.

在某些情況下,完成作業所需的工作量會比以非同步方式啟動作業所需的工作量還少。In some cases, the amount of work required to complete the operation is less than the amount of work required to launch the operation asynchronously. 若資料流中的讀取作業可以藉由已在記憶體中緩衝的資料獲得滿足,則從該資料流進行讀取就是這類情境的範例。Reading from a stream where the read operation can be satisfied by data that is already buffered in memory is an example of such a scenario. 在這類情況下,作業會同步完成,而且可能會傳回已完成的工作。In such cases, the operation may complete synchronously, and may return a task that has already been completed.

例外狀況Exceptions

非同步方法應只有在回應使用方式錯誤時,才引發從非同步方法呼叫擲回例外狀況。An asynchronous method should raise an exception to be thrown out of the asynchronous method call only in response to a usage error. 使用方式錯誤一律不應發生在實際執行程式碼中。Usage errors should never occur in production code. 例如,如果傳遞 Null 參考 (在 Visual Basic 中為 Nothing) 做為方法的其中一個引數造成了錯誤狀態 (通常是以 ArgumentNullException 例外狀況表示),您可以修改呼叫程式碼,確保絕不會傳遞 Null 參考。For example, if passing a null reference (Nothing in Visual Basic) as one of the method’s arguments causes an error state (usually represented by an ArgumentNullException exception), you can modify the calling code to ensure that a null reference is never passed. 對於所有其他錯誤,非同步方法執行時發生的例外狀況應該指派給傳回的工作,即使非同步方法剛好在工作傳回前同步完成也一樣。For all other errors, exceptions that occur when an asynchronous method is running should be assigned to the returned task, even if the asynchronous method happens to complete synchronously before the task is returned. 通常,工作最多只能包含一個例外狀況。Typically, a task contains at most one exception. 不過,如果工作表示多項作業 (例如 WhenAll),則可能會有多個例外狀況與單一工作相關聯。However, if the task represents multiple operations (for example, WhenAll), multiple exceptions may be associated with a single task.

目標環境Target environment

當您實作 TAP 方法時,可以判斷非同步執行發生的位置。When you implement a TAP method, you can determine where asynchronous execution occurs. 您可以選擇在執行緒集區上執行工作負載、使用非同步 I/O (在作業執行過程中大部分時間未繫結至執行緒) 實作它、在特定執行緒 (例如 UI 執行緒) 上執行它,或是使用任意數量的可能內容。You may choose to execute the workload on the thread pool, implement it by using asynchronous I/O (without being bound to a thread for the majority of the operation’s execution), run it on a specific thread (such as the UI thread), or use any number of potential contexts. TAP 方法甚至可能沒有可執行的項目,而且可能只傳回 Task,指出系統中其他位置發生的情形 (例如,代表資料的工作抵達佇列的資料結構)。A TAP method may even have nothing to execute, and may just return a Task that represents the occurrence of a condition elsewhere in the system (for example, a task that represents data arriving at a queued data structure).

TAP 方法的呼叫端可能會透過同步等待產生的工作來阻止等待 TAP 方法完成,或是在非同步作業完成時執行其他 (接續) 程式碼。The caller of the TAP method may block waiting for the TAP method to complete by synchronously waiting on the resulting task, or may run additional (continuation) code when the asynchronous operation completes. 接續程式碼 (Continuation Code) 的建立者可以控制執行程式碼的位置。The creator of the continuation code has control over where that code executes. 您可以明確建立接續程式碼、透過 Task 類別的方法建立 (例如 ContinueWith),或使用建置於接續之上的語言支援以隱含方式建立 (例如 C# 中的 await、Visual Basic 中的 Await,或 F# 中的 AwaitValue)。You may create the continuation code either explicitly, through methods on the Task class (for example, ContinueWith) or implicitly, by using language support built on top of continuations (for example, await in C#, Await in Visual Basic, AwaitValue in F#).

工作狀態Task status

Task 類別會提供非同步作業的生命週期,而該週期是以 TaskStatus 列舉表示。The Task class provides a life cycle for asynchronous operations, and that cycle is represented by the TaskStatus enumeration. 為了支援從 TaskTask<TResult> 衍生的類型隱密案例,以及支援分隔建構與排程,Task 類別會公開 Start 方法。To support corner cases of types that derive from Task and Task<TResult>, and to support the separation of construction from scheduling, the Task class exposes a Start method. 由公用 Task 建構函式所建立的工作稱為「靜止工作」(Cold Task) ,因為這類工作的生命週期是從非排程的 Created 狀態開始,而且只有在這些執行個體上呼叫 Start 時才會排程。Tasks that are created by the public Task constructors are referred to as cold tasks, because they begin their life cycle in the non-scheduled Created state and are scheduled only when Start is called on these instances.

所有其他工作都是從作用狀態開始其生命週期,也就是說,它們所代表的非同步作業已啟始,而且其工作狀態是 TaskStatus.Created 以外的列舉值。All other tasks begin their life cycle in a hot state, which means that the asynchronous operations they represent have already been initiated and their task status is an enumeration value other than TaskStatus.Created. 從 TAP 方法傳回的所有工作都必須為啟用狀態。All tasks that are returned from TAP methods must be activated. 如果 TAP 方法在內部使用工作的建構函式將所要傳回的工作具現化,則 TAP 方法必須先在 Task 物件上呼叫 Start,再將它傳回。If a TAP method internally uses a task’s constructor to instantiate the task to be returned, the TAP method must call Start on the Task object before returning it. TAP 方法的消費者可以安全地假設傳回的工作為作用中,並且不應嘗試在任何從 TAP 方法傳回的 Start 上呼叫 TaskConsumers of a TAP method may safely assume that the returned task is active and should not try to call Start on any Task that is returned from a TAP method. 在作用中工作上呼叫 Start 會導致 InvalidOperationException 例外狀況。Calling Start on an active task results in an InvalidOperationException exception.

取消 (選擇性)Cancellation (optional)

在 TAP 中,取消對於非同步方法實作者和非同步方法消費者而言都是選擇性的。In TAP, cancellation is optional for both asynchronous method implementers and asynchronous method consumers. 如果作業允許取消,則會公開可接受取消語彙基元 (CancellationToken 執行個體) 的非同步方法多載。If an operation allows cancellation, it exposes an overload of the asynchronous method that accepts a cancellation token (CancellationToken instance). 依照慣例,參數會命名為 cancellationTokenBy convention, the parameter is named cancellationToken.

public Task ReadAsync(byte [] buffer, int offset, int count, 
                      CancellationToken cancellationToken)
Public Function ReadAsync(buffer() As Byte, offset As Integer, 
                          count As Integer, 
                          cancellationToken As CancellationToken) _ 
                          As Task

非同步作業會監視取消要求的這個語彙基元。The asynchronous operation monitors this token for cancellation requests. 如果收到取消要求,它可以選擇接受該要求和取消作業。If it receives a cancellation request, it may choose to honor that request and cancel the operation. 如果取消要求導致工作尚未完成就結束,則 TAP 方法會傳回以 Canceled 狀態結束的工作,而且沒有可用的結果,也不會擲回例外狀況。If the cancellation request results in work being ended prematurely, the TAP method returns a task that ends in the Canceled state; there is no available result and no exception is thrown. Canceled 狀態會視為工作的最後 (已完成) 狀態,並且包括 FaultedRanToCompletion 狀態。The Canceled state is considered to be a final (completed) state for a task, along with the Faulted and RanToCompletion states. 因此,如果工作處於 Canceled 狀態,其 IsCompleted 屬性就會傳回 trueTherefore, if a task is in the Canceled state, its IsCompleted property returns true. 當工作以 Canceled 狀態完成時,工作中註冊的任何接續都會排程或執行,除非指定了像是 NotOnCanceled 這類選項來選擇不接續。When a task completes in the Canceled state, any continuations registered with the task are scheduled or executed, unless a continuation option such as NotOnCanceled was specified to opt out of continuation. 任何藉由使用語言功能以非同步方式等候已取消之工作的程式碼都會繼續執行,但是會收到 OperationCanceledException 或從其衍生的例外狀況。Any code that is asynchronously waiting for a canceled task through use of language features continues to run but receives an OperationCanceledException or an exception derived from it. 透過 WaitWaitAll 這類方法封鎖同步等候工作的程式碼也會繼續執行,但會產生例外狀況。Code that is blocked synchronously waiting on the task through methods such as Wait and WaitAll also continue to run with an exception.

如果取消語彙基元在呼叫接受語彙基元的 TAP 方法之前就已要求取消,則 TAP 方法應傳回 Canceled 工作。If a cancellation token has requested cancellation before the TAP method that accepts that token is called, the TAP method should return a Canceled task. 不過,如果是在非同步作業執行時要求取消,則非同步作業不需要接受取消要求。However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. 只有在作業因取消要求而結束時,傳回的工作才應該以 Canceled 狀態結束。The returned task should end in the Canceled state only if the operation ends as a result of the cancellation request. 如果已要求取消,但是仍然產生結果或例外狀況,則工作應以 RanToCompletionFaulted 狀態結束。If cancellation is requested but a result or an exception is still produced, the task should end in the RanToCompletion or Faulted state.

對於想要公開最先取消之能力的非同步方法,您不需要提供不接受取消語彙基元的多載。For asynchronous methods that want to expose the ability to be cancelled first and foremost, you don't have to provide an overload that doesn’t accept a cancellation token. 對於無法取消的方法,請不要提供接受取消語彙基元的多載,這樣有助於向呼叫端表明目標方法實際上是否可以取消。For methods that cannot be canceled, do not provide overloads that accept a cancellation token; this helps indicate to the caller whether the target method is actually cancelable. 不需要取消的消費者程式碼可以呼叫接受 CancellationToken 的方法,並且提供 None 做為引數值。Consumer code that does not desire cancellation may call a method that accepts a CancellationToken and provide None as the argument value. None 在功能上相當於預設的 CancellationTokenNone is functionally equivalent to the default CancellationToken.

進度報告 (選擇性)Progress reporting (optional)

某些非同步作業會因為提供進度通知而受益,這些通知通常用來更新使用者介面並提供有關非同步作業進度的資訊。Some asynchronous operations benefit from providing progress notifications; these are typically used to update a user interface with information about the progress of the asynchronous operation.

在 TAP 中,進度是透過 IProgress<T> 介面處理,並且做為通常名為 progress 的參數傳遞至非同步方法。In TAP, progress is handled through an IProgress<T> interface, which is passed to the asynchronous method as a parameter that is usually named progress. 在呼叫非同步方法時提供進度介面,有助於排除不當使用所造成的競爭情形 (也就是說,事件處理常式在作業啟動後才註冊是不正確的,而這樣可能導致遺失更新)。Providing the progress interface when the asynchronous method is called helps eliminate race conditions that result from incorrect usage (that is, when event handlers that are incorrectly registered after the operation starts may miss updates). 更重要的是,進度介面支援各種不同的進度實作,取決於使用的程式碼。More importantly, the progress interface supports varying implementations of progress, as determined by the consuming code. 例如,使用的程式碼可能只在意最新的進度更新,或是想要緩衝所有更新,也可能想要對每一個更新叫用一個動作,或是想要控制是否要將引動過程封送處理置特定執行緒。For example, the consuming code may only care about the latest progress update, or may want to buffer all updates, or may want to invoke an action for each update, or may want to control whether the invocation is marshaled to a particular thread. 這些選項全都可以使用不同的介面實作達成,並依照消費者的特殊需要自訂。All these options may be achieved by using a different implementation of the interface, customized to the particular consumer’s needs. 就像處理取消一樣,TAP 實作應只在 API 支援進度通知時才提供 IProgress<T> 參數。As with cancellation, TAP implementations should provide an IProgress<T> parameter only if the API supports progress notifications.

例如,如果本文前面所討論的 ReadAsync 方法能夠以目前為止讀取之位元組數目的形式報告中繼進度,則進度回呼就可以是 IProgress<T> 介面:For example, if the ReadAsync method discussed earlier in this article is able to report intermediate progress in the form of the number of bytes read thus far, the progress callback could be an IProgress<T> interface:

public Task ReadAsync(byte[] buffer, int offset, int count, 
                      IProgress<long> progress)
Public Function ReadAsync(buffer() As Byte, offset As Integer, 
                          count As Integer, 
                          progress As IProgress(Of Long)) As Task 

如果 FindFilesAsync 方法傳回符合特定搜尋模式之所有檔案的清單,則進度回呼可提供工作已完成的百分比估計以及目前的部分結果集。If a FindFilesAsync method returns a list of all files that meet a particular search pattern, the progress callback could provide an estimate of the percentage of work completed as well as the current set of partial results. 執行方式可以是使用 Tuple:It could do this either with a tuple:

public Task<ReadOnlyCollection<FileInfo>> FindFilesAsync(
            string pattern, 
            IProgress<Tuple<double, 
            ReadOnlyCollection<List<FileInfo>>>> progress)
Public Function FindFilesAsync(pattern As String, 
                               progress As IProgress(Of Tuple(Of Double, ReadOnlyCollection(Of List(Of FileInfo))))) _
                               As  Task(Of ReadOnlyCollection(Of FileInfo))

或是使用專屬於 API 的資料類型:or with a data type that is specific to the API:

public Task<ReadOnlyCollection<FileInfo>> FindFilesAsync(
    string pattern, 
    IProgress<FindFilesProgressInfo> progress)
Public Function FindFilesAsync(pattern As String, 
                               progress As IProgress(Of FindFilesProgressInfo)) _
                               As Task(Of ReadOnlyCollection(Of FileInfo))

在後者的情況下,特殊資料類型通常會加上 ProgressInfo 尾碼。In the latter case, the special data type is usually suffixed with ProgressInfo.

如果 TAP 實作提供接受 progress 參數的多載,則必須允許 null 引數,而這種情況下就不會報告進度。If TAP implementations provide overloads that accept a progress parameter, they must allow the argument to be null, in which case no progress will be reported. TAP 實作應對 Progress<T> 物件同步報告進度,如此可讓非同步方法快速提供進度,並且讓進度消費者判斷處理資訊的最佳方式和位置。TAP implementations should report the progress to the Progress<T> object synchronously, which enables the asynchronous method to quickly provide progress, and allow the consumer of the progress to determine how and where best to handle the information. 例如,進度執行個體可以選擇在擷取的同步處理內容上封送處理回呼並引發事件。For example, the progress instance could choose to marshal callbacks and raise events on a captured synchronization context.

IProgress<T> 實作IProgress<T> implementations

.NET Framework 4.5 提供單一 IProgress<T> 實作:Progress<T>The .NET Framework 4.5 provides a single IProgress<T> implementation: Progress<T>. Progress<T> 類別的宣告方式如下:The Progress<T> class is declared as follows:

public class Progress<T> : IProgress<T>  
{  
    public Progress();  
    public Progress(Action<T> handler);  
    protected virtual void OnReport(T value);  
    public event EventHandler<T> ProgressChanged;  
}  
Public Class Progress(Of T) : Inherits IProgress(Of T)  
    Public Sub New()  
    Public Sub New(handler As Action(Of T))  
    Protected Overridable Sub OnReport(value As T)  
    Public Event ProgressChanged As EventHandler(Of T>  
End Class  

Progress<T> 執行個體會公開 ProgressChanged 事件,該事件是在每次非同步作業報告進度更新時引發。An instance of Progress<T> exposes a ProgressChanged event, which is raised every time the asynchronous operation reports a progress update. ProgressChanged 事件是在具現化 SynchronizationContext 執行個體時所擷取的 Progress<T> 物件上引發。The ProgressChanged event is raised on the SynchronizationContext object that was captured when the Progress<T> instance was instantiated. 如果沒有可用的同步處理內容,則會使用以執行緒集區為目標的預設內容。If no synchronization context was available, a default context that targets the thread pool is used. 處理常式可能會向這個事件註冊。Handlers may be registered with this event. 為了方便起見,您也可以對 Progress<T> 建構函式提供單一處理常式,該處理常式的行為就像是 ProgressChanged 事件的事件處理常式。A single handler may also be provided to the Progress<T> constructor for convenience, and behaves just like an event handler for the ProgressChanged event. 進度更新會以非同步方式引發,以避免在事件處理常式執行時延遲非同步作業。Progress updates are raised asynchronously to avoid delaying the asynchronous operation while event handlers are executing. 另一個 IProgress<T> 實作可以選擇套用不同的語意。Another IProgress<T> implementation could choose to apply different semantics.

選擇要提供的多載Choosing the overloads to provide

如果 TAP 實作同時使用了選擇性的 CancellationToken 和選擇性的 IProgress<T> 參數,則最多可能會需要四個多載:If a TAP implementation uses both the optional CancellationToken and optional IProgress<T> parameters, it could potentially require up to four overloads:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, CancellationToken cancellationToken);  
public Task MethodNameAsync(…, IProgress<T> progress);   
public Task MethodNameAsync(…,   
    CancellationToken cancellationToken, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken cancellationToken) As Task  
Public MethodNameAsync(…, progress As IProgress(Of T)) As Task   
Public MethodNameAsync(…, cancellationToken As CancellationToken,   
                       progress As IProgress(Of T)) As Task  

然而,許多 TAP 實作都不提供取消或進度功能,因此這些實作需要單一方法:However, many TAP implementations provide neither cancellation or progress capabilities, so they require a single method:

public Task MethodNameAsync(…);  
Public MethodNameAsync(…) As Task  

如果 TAP 實作支援取消或進度,但不是同時支援兩者,它可能會提供兩個多載:If a TAP implementation supports either cancellation or progress but not both, it may provide two overloads:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, CancellationToken cancellationToken);  
  
// … or …  
  
public Task MethodNameAsync(…);  
public Task MethodNameAsync(…, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken) As Task  
  
' … or …  
  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, progress As IProgress(Of T)) As Task  

如果 TAP 實作同時支援取消和進度,它可能會公開全部四個多載。If a TAP implementation supports both cancellation and progress, it may expose all four overloads. 但是,它只會提供下列兩者:However, it may provide only the following two:

public Task MethodNameAsync(…);  
public Task MethodNameAsync(…,   
    CancellationToken cancellationToken, IProgress<T> progress);  
Public MethodNameAsync(…) As Task  
Public MethodNameAsync(…, cancellationToken As CancellationToken,   
                       progress As IProgress(Of T)) As Task  

為了彌補兩個遺漏的中繼組合,開發人員可以針對 None 參數傳遞 CancellationToken 或預設的 cancellationToken,並且針對 null 參數傳遞 progressTo compensate for the two missing intermediate combinations, developers may pass None or a default CancellationToken for the cancellationToken parameter and null for the progress parameter.

如果您期望 TAP 方法的每一種用法都支援取消或進度,可以省略不接受相關參數的多載。If you expect every usage of the TAP method to support cancellation or progress, you may omit the overloads that don’t accept the relevant parameter.

如果您決定公開多個多載,讓取消或進度成為選擇項,則不支援取消或進度的多載行為應該就像已針對取消傳遞 None 或針對進度傳遞 null 至支援兩者的多載。If you decide to expose multiple overloads to make cancellation or progress optional, the overloads that don’t support cancellation or progress should behave as if they passed None for cancellation or null for progress to the overload that does support these.

標題Title 說明Description
非同步程式設計模式Asynchronous Programming Patterns 介紹執行非同步作業的三種模式:工作式非同步模式 (TAP)、非同步程式設計模型 (APM) 和事件式非同步模式 (EAP)。Introduces the three patterns for performing asynchronous operations: the Task-based Asynchronous Pattern (TAP), the Asynchronous Programming Model (APM), and the Event-based Asynchronous Pattern (EAP).
實作以工作為基礎的非同步模式Implementing the Task-based Asynchronous Pattern 描述三種實作工作式非同步模式 (TAP) 的方式:使用 Visual Studio 中的 C# 和 Visual Basic 編譯器、手動,或是透過編譯器和手動方法的組合。Describes how to implement the Task-based Asynchronous Pattern (TAP) in three ways: by using the C# and Visual Basic compilers in Visual Studio, manually, or through a combination of the compiler and manual methods.
Consuming the Task-based Asynchronous PatternConsuming the Task-based Asynchronous Pattern 描述如何使用工作和回呼達到等待的目的,而不會遭到封鎖。Describes how you can use tasks and callbacks to achieve waiting without blocking.
與其他非同步模式和型別互通Interop with Other Asynchronous Patterns and Types 描述如何使用工作式非同步模式 (TAP) 實作非同步程式設計模型 (APM) 和事件式非同步模式 (EAP)。Describes how to use the Task-based Asynchronous Pattern (TAP) to implement the Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP).