/// <summary> /// Collects batchSize elements from an LdapSearchQueue message /// queue and places them in a Vector. /// If the last message from the server, /// the result message, contains an error, it will be stored in the Vector /// for nextElement to process. (although it does not increment the search /// result count) All search result entries will be placed in the Vector. /// If a null is returned from getResponse(), it is likely that the search /// was abandoned. /// </summary> /// <param name="cancellationToken"></param> /// <returns> /// true if all search results have been placed in the vector. /// </returns> private async Task <bool> GetBatchOfResultsAsync(CancellationToken cancellationToken) { LdapMessage msg; // <=batchSize so that we can pick up the result-done message for (var i = 0; i < _batchSize;) { try { if ((msg = await _queue.GetResponse(cancellationToken).ConfigureAwait(false)) != null) { // Only save controls if there are some var ctls = msg.Controls; if (ctls != null) { ResponseControls = ctls; } if (msg is LdapSearchResult) { // Search Entry object entry = ((LdapSearchResult)msg).Entry; _entries.Add(entry); i++; _entryCount++; } else if (msg is LdapSearchResultReference) { // Search Ref var refs = ((LdapSearchResultReference)msg).Referrals; if (_cons.ReferralFollowing) { _referralConn = await _conn.ChaseReferralAsync(_queue, _cons, msg, refs, 0, true, _referralConn, cancellationToken).ConfigureAwait(false); } else { _references.Add(refs); _referenceCount++; } } else { // LdapResponse var resp = (LdapResponse)msg; var resultCode = resp.ResultCode; // Check for an embedded exception if (resp.HasException()) { // Fake it, results in an exception when msg read resultCode = LdapException.ConnectError; } if (resultCode == LdapException.Referral && _cons.ReferralFollowing) { // Following referrals _referralConn = await _conn.ChaseReferralAsync(_queue, _cons, resp, resp.Referrals, 0, false, _referralConn, cancellationToken : cancellationToken).ConfigureAwait(false); } else if (resultCode != LdapException.Success) { // Results in an exception when message read _entries.Add(resp); _entryCount++; } // We are done only when we have read all messages // including those received from following referrals var msgIDs = _queue.MessageIDs; var controls = _cons.GetControls(); if (msgIDs.Length == 0 && (controls == null || controls.Length == 0)) { // Release referral exceptions await _conn.ReleaseReferralConnections(_referralConn, cancellationToken).ConfigureAwait(false); return(true); // search completed } } } else { // We get here if the connection timed out // we have no responses, no message IDs and no exceptions var e = new LdapException(null, LdapException.LdapTimeout, null); _entries.Add(e); break; } } catch (LdapException e) { // Hand exception off to user _entries.Add(e); } } return(false); // search not completed }