Пагинация
Одна страница, все страницы или по одному элементу.
Одна страница
var page = await client.Threads.ListAsync(folder: "inbox", limit: 25); foreach (var thread in page){ Console.WriteLine(thread["id"]);} if (page.HasMore){ var next = await client.Threads.ListAsync(folder: "inbox", limit: 25, cursor: page.NextCursor); Console.WriteLine(next.Count);}Метод ListAsync возвращает Page с Items, HasMore и NextCursor, а foreach обходит её элементы. Передайте NextCursor обратно как cursor: с теми же фильтрами, чтобы прочитать следующую страницу.
Все страницы
var failed = await client.Emails.ListAllAsync(status: new[] { "failed" }); Console.WriteLine($"{failed.Count} messages failed");Метод ListAllAsync идёт по курсору до конца и возвращает все элементы в одном списке. Сбой на любой странице проваливает весь вызов.
По одному элементу
await foreach (var contact in client.Contacts.IterateAsync(limit: 100)){ if ((string?)contact["email"] == "[email protected]") { break; }} await foreach (var entry in client.Emails.IterateEventsAsync("msg_3f9a1c07d2b84e6a9c5b1f20")){ Console.WriteLine(entry["type"]);}Метод IterateAsync возвращает IAsyncEnumerable<JsonObject>, который запрашивает следующую страницу, только когда цикл до неё доходит, поэтому break останавливает запросы. У каждого постраничного списка есть все три метода, названные по списку, который они обходят: ListAllEventsAsync и IterateEventsAsync рядом с ListEventsAsync.
Обход останавливается, когда API повторяет курсор, по которому он уже прошёл, поэтому он не может зациклиться навсегда.