分页图数据
Paging Graph Data
我检查了 Stack 上的多个分页线程,但无法制作代码的功能副本。
我知道在下面的例子中,图表 returns 每页 200 项,如果我想要 foreach
所有的项目,我需要切换到下一页。请检查以下代码并告诉我我做错了什么。
总是在调用 NextPageRequest.GetAsync()
的捕获中抛出异常。
此代码的结果是仅删除了 3xx 项中的 200 项。
var deleteListItems = new List<Microsoft.Graph.ListItem>();
var deleteListItemsPage = await graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items
.Request(deleteQueryOptions)
.GetAsync();
deleteListItems.AddRange(deleteListItemsPage.CurrentPage);
do
{
foreach (var deleteItem in deleteListItemsPage)
{
awaitTasks.Add(graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items[deleteItem.Id]
.Request()
.DeleteAsync());
}
try
{
Task.WaitAll(awaitTasks.ToArray());
}
catch
{
Console.WriteLine("ERROOR executing the tasks");
}
Console.WriteLine("Another PAGE of List Items successfully deleted");
try
{
deleteListItemsPage = await deleteListItemsPage.NextPageRequest.GetAsync();
deleteListItems.AddRange(deleteListItemsPage.CurrentPage);
}
catch
{
Console.WriteLine("There is no NextPageRequest for deleting items or ERROR occured.");
}
} while (deleteListItemsPage.NextPageRequest != null);
几点观察:
Task.WaitAll
模式在技术上是正确的,但在实践中,它很容易出现人为错误。您应该始终使用 async
/await
模式,除非有非常令人信服的技术理由不这样做。它会让你省去很多麻烦。
你永远不应该使用空的 catch { }
子句,除非你想在没有警告或上下文的情况下吃掉任何异常(FTR,你 不要 想要这个)。至少,您应该捕获通用 System.Exception
并将其分配给一个变量 (catch (Exception e) {}
),即使您使用它做的唯一事情是将异常记录到控制台 (catch (Exception e) { Console.WriteLine(e); }
).
当你知道一个对象有可能成为null
时,你应该总是检查 null
而不是依赖一个Try/Catch。 Try/Catch 模式依赖于比简单的空检查贵 很多 的异常。
对于这样的场景,更好的模式应该是这样的:
private async Task DeleteItems()
{
// Construct the HTTP Request but DO NOT execute it just yet
var deleteListItemsRequest = graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items
.Request(deleteQueryOptions);
// This loop is for iterating over the pages
do
{
// Populate the page by executing the HTTP request
var deleteListItemsPage = deleteListItemsRequest.GetAsync();
// Iterate over the current page
foreach (var listItem in deleteListItemsPage.CurrentPage)
{
// Execute the delete and wait for the response
await graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items[deleteItem.Id]
.Request()
.DeleteAsync();
}
// Check for additional pages
if (deleteListItemsPage.NextPageRequest != null)
{
// If we have an additional page, assign it to the
// same HTTP Request object. Again, we DO NOT execute
// yet. It will get executed at the top of the loop
deleteListItemsRequest = deleteListItemsPage.NextPageRequest;
}
else
{
// If we don't have an additional page, set the current
// request to null so we can use this to trigger an exit
// from the loop
deleteListItemsRequest = null;
}
// Check if we have a Graph request, if not break out of the loop
} while (deleteListItemsRequest != null);
}
我检查了 Stack 上的多个分页线程,但无法制作代码的功能副本。
我知道在下面的例子中,图表 returns 每页 200 项,如果我想要 foreach
所有的项目,我需要切换到下一页。请检查以下代码并告诉我我做错了什么。
总是在调用 NextPageRequest.GetAsync()
的捕获中抛出异常。
此代码的结果是仅删除了 3xx 项中的 200 项。
var deleteListItems = new List<Microsoft.Graph.ListItem>();
var deleteListItemsPage = await graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items
.Request(deleteQueryOptions)
.GetAsync();
deleteListItems.AddRange(deleteListItemsPage.CurrentPage);
do
{
foreach (var deleteItem in deleteListItemsPage)
{
awaitTasks.Add(graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items[deleteItem.Id]
.Request()
.DeleteAsync());
}
try
{
Task.WaitAll(awaitTasks.ToArray());
}
catch
{
Console.WriteLine("ERROOR executing the tasks");
}
Console.WriteLine("Another PAGE of List Items successfully deleted");
try
{
deleteListItemsPage = await deleteListItemsPage.NextPageRequest.GetAsync();
deleteListItems.AddRange(deleteListItemsPage.CurrentPage);
}
catch
{
Console.WriteLine("There is no NextPageRequest for deleting items or ERROR occured.");
}
} while (deleteListItemsPage.NextPageRequest != null);
几点观察:
Task.WaitAll
模式在技术上是正确的,但在实践中,它很容易出现人为错误。您应该始终使用async
/await
模式,除非有非常令人信服的技术理由不这样做。它会让你省去很多麻烦。你永远不应该使用空的
catch { }
子句,除非你想在没有警告或上下文的情况下吃掉任何异常(FTR,你 不要 想要这个)。至少,您应该捕获通用System.Exception
并将其分配给一个变量 (catch (Exception e) {}
),即使您使用它做的唯一事情是将异常记录到控制台 (catch (Exception e) { Console.WriteLine(e); }
).当你知道一个对象有可能成为
null
时,你应该总是检查null
而不是依赖一个Try/Catch。 Try/Catch 模式依赖于比简单的空检查贵 很多 的异常。
对于这样的场景,更好的模式应该是这样的:
private async Task DeleteItems()
{
// Construct the HTTP Request but DO NOT execute it just yet
var deleteListItemsRequest = graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items
.Request(deleteQueryOptions);
// This loop is for iterating over the pages
do
{
// Populate the page by executing the HTTP request
var deleteListItemsPage = deleteListItemsRequest.GetAsync();
// Iterate over the current page
foreach (var listItem in deleteListItemsPage.CurrentPage)
{
// Execute the delete and wait for the response
await graphServiceClient
.Sites[siteUrl]
.Lists[listName]
.Items[deleteItem.Id]
.Request()
.DeleteAsync();
}
// Check for additional pages
if (deleteListItemsPage.NextPageRequest != null)
{
// If we have an additional page, assign it to the
// same HTTP Request object. Again, we DO NOT execute
// yet. It will get executed at the top of the loop
deleteListItemsRequest = deleteListItemsPage.NextPageRequest;
}
else
{
// If we don't have an additional page, set the current
// request to null so we can use this to trigger an exit
// from the loop
deleteListItemsRequest = null;
}
// Check if we have a Graph request, if not break out of the loop
} while (deleteListItemsRequest != null);
}