程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 並發事件:使用AsyncEnumerator簡化APM(4)

並發事件:使用AsyncEnumerator簡化APM(4)

編輯:關於C語言

AsyncEnumerator 的體系結構

AsyncEnumerator 類可定義圖 3 中顯示的私有字段。 m_enumerator 字段指您的迭代器成員,構造函數會將此字段初始化為空,然後 Execute 會將此字段設置 為傳遞給它的值。m_inbox 字段指 IAsyncResult 對象的集合。m_waitAndInboxCounts 字段是一個包含 有兩個 16 位整數值的結構;在本專欄的稍後部分,我將介紹如何使用這些值。

圖 3 AsyncEnumerator 字段

public partial class AsyncEnumerator {
  // Refers to the iterator member's code
  private IEnumerator<Int32> m_enumerator;
  // Collection of completed async Operations (the inbox)
  private List<IAsyncResult> m_inbox =
   new List<IAsyncResult>();
  // Structure with Wait & Inbox counters
  private WaitAndInboxCounts m_waitAndInboxCounts;
}

正如我在上期專欄中所介紹的,要使編譯器創建用於實現 IEnumerator<T> 接口的類,使用迭 代器確實是一種簡便方式。通常,您會使用 foreach 語句遍歷 IEnumerator<T> 對象。不過,無 論何時您都可以顯式調用代碼中的 IEnumerator<T> MoveNext 方法和 Current 屬性,這正是 AsyncEnumerator 類的作用。

AsyncEnumerator 的 Execute 方法將在內部調用名為 ResumeIterator 的私有方法(如圖 4 中所示 )。此方法用於啟動迭代器,還可用於使迭代器從暫停狀態恢復執行。

圖 4 ResumeIterator

private void ResumeIterator() {
  Boolean continueIterating;
  // While there are more Operations to perform...
  while (continueIterating = m_enumerator.MoveNext()) {
    // Get the value returned from the enumerator
    UInt16 numberOpsToWaitFor = checked((UInt16) m_enumerator.Current);
    // If inbox has fewer items than requested, keep iterator suspended
    if (!m_waitAndInboxCounts.AtomicSetWait(numberOpsToWaitFor)) break;
    // Inbox has enough items, loop to resume the iterator
  }
  // The iterator is suspended, just return
  if (continueIterating) return;
  // The iterator has exited, execute the iterator's finally code
  m_enumerator.Dispose();
}

當線程調用 ResumeIterator 時,它將調用 IEnumerator<T> MoveNext 方法,用於喚醒並運行 迭代器。如果迭代器退出或執行 yield break 語句,IEnumerator<T> MoveNext 方法將返回 false,表明它沒有可執行的操作。如果將 ResumeIterator 方法的 continueIterating 變量設置為 false,它將退出此循環,並調用 IEnumerator<T> 對象的 Dispose 方法,允許執行清理。然後, ResumeIterator 方法將返回值,因為迭代器已完成其所有工作。

另一方面,如果枚舉器對象的 MoveNext 方法返回 true,則表明它已啟動了一些異步操作,並已通過 執行 yield return 語句暫停運行。現在,ResumeIterator 方法需要知道 IEnumerator<T> 對象 在其 yield return 語句中指定的數字。此數字指示在恢復運行迭代器之前應完成的異步操作數。為了獲 得此數字,ResumeIterator 將查詢枚舉器對象的 Current 屬性;此屬性將返回上次通過 yIEld return 語句指定的值。

隨後,ResumeIterator 將調用 WaitAndInboxCounts AtomicSetWait 方法,該方法用於設置迭代器應 等待的項目數。如果 AtomicSetWait 發現收件箱中的項目數少於此等待計數,則 AtomicSetWait 將返回 false,這會導致 ResumeIterator 返回值,因為此線程沒有其他任務可執行。如果 AtomicSetWait 發現 收件箱中的項目數大於或等於等待計數,則 AtomicSetWait 將返回 true 並繼續循環,從而再次調用枚 舉器對象的 MoveNext 方法,並允許迭代器恢復執行,以便處理已完成的操作。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved