问题描述
我正在开发一个 ASP.NET 应用程序,除其他外,它应该从 Azure Active Directory 检索用户.为此,我使用了 Microsoft Graph 版本 1.14.0 预览库,可以在 这里.
I am developing an ASP.NET application which, among other things, is supposed to retrieve users from Azure Active Directory. For this purpose, I am using the Microsoft Graph version 1.14.0 preview library, which can be found here.
由于这个库只提供了检索用户的异步方法,我使用下面的(伪)代码来同步运行它.
As this library only provides asynchronous methods for retrieving users, I am using the following (pseudo) code to run it synchronously.
string userPrincipalName = "test.user@intuneforeducation.com";
var task = Task.Run(async () => await _graphServiceClient.Users[userPrincipalName].Request().GetAsync());
while (!task.IsCompleted)
Thread.Sleep(200);
User retrievedUser = task.Result;
问题
我现在面临的问题是,在从 ASP.NET 应用程序调用这段代码时,task.IsCompleted
永远保持为 false
.现在这是我无法理解的奇怪部分:代码在控制台应用程序和单元测试中都能完美运行(使用 NUnit).
Problem
The problem I am facing right now is that upon calling this piece of code from the ASP.NET application, task.IsCompleted
remains forever false
. Now here is the strange part which I can not wrap my head around: the code runs perfectly in both a Console Application and a Unit Test (using NUnit).
人们可能会认为 GraphServiceClient 实例在这些版本中的构建方式不同,但我 100% 肯定它不是.组成它的信息是从数据库中加载的,单元测试中的代码与 ASP.NET 应用程序控制器中的代码完全相同相同.使用单元测试,上述代码在大约 1.5 秒内执行完毕.在 ASP.NET 应用程序中,我让它运行了长达 30 分钟,没有任何结果,没有错误,没有超时,什么都没有.
One might think that the GraphServiceClient instance is built differently in these versions, but I am 100% positive that it is not. The information that makes it up is loaded from a database, and the code in the Unit Test is exactly the same as the code in the controller of the ASP.NET application. Using the Unit Test, the above code is executed in about 1.5 seconds. In the ASP.NET application, I left it running for as long as 30 minutes without any results, no errors, no time-outs, nothing at all.
我意识到这可能是一个小众问题,但我确实希望有人遇到同样的问题并能够解决它.
I realize this might be a bit of a niche problem, but I do hope that someone has run into the same problem and was able to resolve it.
我设法解决了这个问题.奇怪的是,将我所有的方法转换为异步任务都不起作用,因为甚至 await
一直挂起.但是,我不完全理解为什么我的解决方案现在有效.看起来我的伪代码并不完全准确,解决方案就在其中.
I managed to resolve this issue. Weirdly enough, converting all my methods to async Tasks did not work, as even await
kept hanging. I do however not fully understand why my solution works now. It looks as though my pseudo-code was not fully accurate, and the solution lies therein.
此代码将永远保留在 while (!runTask.IsCompleted)
中.
This code remains forever in while (!runTask.IsCompleted)
.
object GetResult<TResult>(Task<TResult> task)
{
using (task)
using (var runTask = Task.Run(async () => await task))
{
while (!runTask.IsCompleted)
Thread.Sleep(SleepTime);
if (runTask.Exception != null)
throw runTask.Exception.InnerException ?? runTask.Exception;
return runTask.Result;
}
}
User GetUser(string userPrincipalName)
{
return (User)GetResult(_graphServiceClient.Users[userPrincipalName].Request().GetAsync());
}
尝试#2(不起作用)
这个方法在执行 await
行之后一直挂起.
async Task<User> GetUser(string userPrincipalName)
{
User user = await _graphServiceClient.Users[userPrincipalName].Request().GetAsync();
return user;
}
尝试#3(有效)
此代码与尝试 #1 中的代码基本相同,唯一的区别是它不使用 GetResult
方法,但它使用与 GetResult 完全相同的方法
.
Attempt#3(works)
This code is basically the same as the code in attempt #1, the only difference being that it does not use the GetResult
method, but it does use the exact same approach as GetResult
.
User GetUser(string userPrincipalName)
{
using(var task = Task.Run(async () => await _graphServiceClient.Users[userPrincipalName].Request().GetAsync()))
{
while (!task.IsCompleted)
Thread.Sleep(200);
return task.Result;
}
}
虽然这种方法可能不被视为最佳做法,但它确实有效.我对为什么这种方法有效感到非常困惑,因为尝试 #1 中的代码没有,而且它实际上是相同的代码.谁能解释这是为什么?
While this approach might not be considered best practice, it does work. I am extremely puzzled about why this approach works, because the code in attempt #1 does not, and it is virtually the same code. Can anybody explain why that is?
推荐答案
我遇到了同样的问题 (见这里).我通过恢复 Microsoft.Graph
和 Microsoft.Graph.Core
版本 1.12.0 解决了这个问题.
I had the same issue (see here). I solved it by reverting Microsoft.Graph
and Microsoft.Graph.Core
version 1.12.0.
这篇关于Microsoft.Graph GetAsync() 无限期挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!