我正在使用Microsoft Graph API库(C#),想知道是否有人遇到过这种情况:
我的许多图形API调用有时都会超时。
从获取当前用户配置文件到获取共享点文档等任何API调用都可能发生这种情况。
我尝试将Microsoft Graph API和相关的Nuget软件包更新到最新版本,但这无济于事。
为澄清起见,此应用程序是Windows控制台应用程序。在Azure方面,它已注册为本地应用程序。作为测试应用程序,它是一个单线程应用程序。不涉及并发,竞争条件。代码逻辑就像
例如1。
var currentUser = graphClient.Me.Request().GetAsync().Result;
例如2。
var site = _graphClient.Sites[SharePointSiteId].Request().GetAsync().Result;
症状在一两分钟后,它抛出一个AggregationException(由于TPL),其中包括TimeOutException。
没有未经授权的例外。
我想知道可能是什么原因以及如何避免这种情况。
更新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()
答案 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来限制它发送回的项目的大小/数量。