內容
本文件說明並行執行階段中內容的角色。 附加至排程器的執行緒稱為「執行內容」(Execution Context),或簡稱為「內容」(Context)。 Concurrency::wait 函式和 concurrency::Context 類別可讓您控制行為的內容。 使用 wait 函式來暫停目前內容一段指定的時間。 當您需要控制何時內容封鎖、解除封鎖及讓渡時,或當您要過度訂閱目前內容時,請使用 Context 類別。
提示
並行執行階段提供了預設排程器,因此您不需要在應用程式中建立排程器。因為工作排程器有助於微調應用程式效能,如果您是並行執行階段的新使用者,建議請從平行模式程式庫 (PPL) 或非同步代理程式程式庫開始。
wait 函式
Concurrency::wait 函式相互合作地會產生指定的毫秒數的目前內容的執行。 執行階段可使用產生時間來執行其他工作。 經過指定的時間之後,執行階段會重新排程要執行的內容。 因此,wait 函式暫止目前內容的時間,可能會超過為 milliseconds 參數所提供的值。
傳遞 0 (零) 做為 milliseconds 參數值,會導致執行階段暫止目前的內容,直到所有其他作用中的內容有機會執行工作為止。 這可讓您產生工作,而使所有其他作用中的工作得以執行。
範例
如需相關範例,以了解如何使用 wait 函式來讓渡目前的內容,而讓其他內容得以執行,請參閱 HOW TO:使用排程群組來影響執行順序。
Context 類別
Concurrency::Context 類別提供的執行內容的程式設計抽象概念,並提供兩項重要功能: 能夠相互合作地封鎖、 解除封鎖之後,及產生目前的內容,並且能夠 oversubscribe 目前的內容。
合作式封鎖
Context 類別可讓您封鎖或產生目前的執行內容。 當目前的內容因資源無法使用而無法繼續執行時,封鎖或讓渡非常有用。
Concurrency::Context::Block 方法會一直封鎖目前的內容。 被封鎖的內容會產生其處理資源,使執行階段得以執行其他工作。 Concurrency::Context::Unblock 方法解除封鎖已封鎖的內容。 呼叫 Context::Unblock 方法的來源內容,必須與呼叫 Context::Block 的來源內容不同。 執行階段就會擲回 concurrency::context_self_unblock 如果想要解除封鎖本身的內容。
若要相互合作地封鎖並解除封鎖的內容,通常可以呼叫 concurrency::Context::CurrentContext 擷取變數的指標, Context及儲存結果的與目前執行緒相關聯的物件。 接著,您可以呼叫 Context::Block 方法,以封鎖目前的內容。 接下來,請從個別的內容呼叫 Context::Unblock,將已封鎖的內容解除封鎖。
每次呼叫 Context::Block 和 Context::Unblock 時都必須成對出現。 執行階段就會擲回 concurrency::context_unblock_unbalanced 時Context::Block或Context::Unblock而不需符合呼叫其他方法連續呼叫方法。 但在您呼叫 Context::Unblock 之前,並不需要呼叫 Context::Block。 例如,如果在一項內容呼叫 Context::Unblock 之後,另一項內容對相同的內容呼叫了 Context::Block,第一項內容仍會維持為解除封鎖的狀態。
Concurrency::Context::Yield 方法讓出執行權,讓執行階段可以執行其他工作,並再重新執行的內容。 當您呼叫 Context::Block 方法時,執行階段不會重新排程內容。
範例
如需使用 Context::Block、Context::Unblock 和 Context::Yield 方法實作合作式信號類別的範例,請參閱 HOW TO:使用內容類別實作合作式信號。
過度訂閱
有可用的硬體執行緒時,預設排程器會建立相同數目的執行緒。 您可以使用「過度訂閱」(Oversubscription),為指定的硬體執行緒建立其他執行緒。
執行密集運算作業時通常不會增加過度訂閱量,因為這樣會加重額外負荷。 但就延遲性較高的工作而言 (例如從磁碟或網路連接讀取資料),過度訂閱將可改善某些應用程式的整體效率。
注意事項 |
---|
可讓只能從一個執行緒所建立的並行執行階段的過度訂閱。從不是由執行階段所建立的執行緒 (包含主執行緒) 呼叫過度訂閱時,過度訂閱並沒有作用。 |
若要啟用過度訂閱目前內容中的,呼叫 concurrency::Context::Oversubscribe 方法以_BeginOversubscription參數設為true。 在並行執行階段所建立的執行緒中啟用過度訂閱時,執行階段將因此而建立一個額外的執行緒。 在所有需要過度訂閱的工作完成後,請將 _BeginOversubscription 參數設為 false,然後呼叫 Context::Oversubscribe。
您可以從目前的內容啟用過度訂閱多次,但您加以停用的次數必須與其啟用次數相同。 過度訂閱也可以是巢狀的;也就是說,由另一項使用過度訂閱的工作所建立的工作,也可過度訂閱其內容。 但如果巢狀工作及其父代屬於相同的內容,則只有最外層的 Context::Oversubscribe 呼叫會建立額外的執行緒。
注意事項 |
---|
執行階段就會擲回 concurrency::invalid_oversubscribe_operation 如果過度訂閱被停用,才能啟用它。 |
範例
如需相關範例以了解如何使用過度訂閱緩解從網路連接讀取資料時所產生的延遲,請參閱 HOW TO:使用過度訂閱使延遲產生位移。