Microsoft Graph API超时异常

时间:2019-06-05 18:10:31

标签: c# sharepoint microsoft-graph sharepoint-online

我正在使用Microsoft Graph API库(C#),想知道是否有人遇到过这种情况:
我的许多图形API调用有时都会超时。
从获取当前用户配置文件到获取共享点文档等任何API调用都可能发生这种情况。 我尝试将Microsoft Graph API和相关的Nuget软件包更新到最新版本,但这无济于事。

为澄清起见,此应用程序是Windows控制台应用程序。在Azure方面,它已注册为本地应用程序。作为测试应用程序,它是一个单线程应用程序。不涉及并发,竞争条件。代码逻辑就像

一样简单
  1. 用户登录。
  2. 程序进行Graph API调用(如例1所示)以获取用户的个人资料,并且此API调用超时。

例如1。

var currentUser = graphClient.Me.Request().GetAsync().Result;

例如2。

var site = _graphClient.Sites[SharePointSiteId].Request().GetAsync().Result;

症状在一两分钟后,它抛出一个AggregationException(由于TPL),其中包括TimeOutException。
没有未经授权的例外。

我想知道可能是什么原因以及如何避免这种情况。


更新: 这是发生异常时的屏幕截图。 enter image description here


更新2: 我尝试替换所有API调用以直接使用“ await”来等待结果。因为此示例代码是控制台应用程序。我放

static void Main(string[] args)
{
    // using Stephen Cleary's nuget package: Nito.AsyncEx.Tasks
    MainImp().WaitAndUnwrapException();
}

static async Task MainImp()
{
    // ...
    // Graph API calls

此简单的API调用仍会引发此异常:

var currentUser = await graphClient.Me.Request().GetAsync();

mscorlib.dll中发生了'Microsoft.Graph.ServiceException'类型的未处理异常 附加信息:代码:超时

这是完整的通话堆栈

  

在Microsoft.Graph.HttpProvider.d__19.MoveNext()   ---从上一个引发异常的位置开始的堆栈跟踪-   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务),位于Microsoft.Graph.HttpProvider.d__18.MoveNext()   ---从上一个引发异常的位置开始的堆栈跟踪-   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.Graph.BaseRequest.d__35.MoveNext()   ---从上一个引发异常的位置开始的堆栈跟踪-   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务),网址为Microsoft.Graph.BaseRequest.d__31 1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Graph.UserRequest.<GetAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()   在SharePointConsoleApp.Program.d__14.MoveNext()中   D:\ TestProjects \ SharePointConsoleApp \ Program.cs:第133行   ---从上一个引发异常的位置开始的堆栈跟踪-   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(任务   任务)在SharePointConsoleApp.Program.Main(String [] args)中   D:\ TestProjects \ SharePointConsoleApp \ Program.cs:第50行位于   System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,字符串[]   args)位于System.AppDomain.ExecuteAssembly(String assemblyFile,   证据assemblySecurity,String [] args)在   Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)处
  在System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   reserveSyncCtx)位于   System.Threading.ExecutionContext.Run(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   reserveSyncCtx)位于   System.Threading.ExecutionContext.Run(ExecutionContext   executeContext,ContextCallback回调,对象状态),位于   System.Threading.ThreadHelper.ThreadStart()

2 个答案:

答案 0 :(得分:0)

首先,如果它是具有用户交互作用的应用程序,则永远不要在主线程上阻塞(.Wait().Result)调用,这将锁定应用程序以进行进一步的用户交互。 / p>

因此,您需要使用异步代码开始,这是一个异步Button_Click处理程序的示例。它会警告您,但这似乎是异步void的用例之一。

private async void Button_Click(object sender, RoutedEventArgs 
{
    var currentUser = await graphClient.Me.Request().GetAsync();
    // Presumably do something with the response
    labelUser.Text = currentUser.DisplayName;
}

几天前,我发现了一个nice video关于常见的异步/等待错误

您似乎在谈论在Windows上运行的控制台应用程序。

从C#7.1开始,您还可以使用public static Task Main(string[] args)作为起点。然后您的应用程序将如下所示:

public static async Task Main(string[] args) {
  // Create the client here.....
  var graphClient = .....;
  // Await every call to the graphclient
  var currentUser = await graphClient.Me.Request().GetAsync();
  // Do something with the user

}

答案 1 :(得分:0)

在处理请求超时时,您收到的响应(有效负载)可能非常大吗?我在摆弄图API时经常遇到这个问题,所以我使用pagination来限制它发送回的项目的大小/数量。