Исключение тайм-аута API-интерфейса Microsoft Graph - PullRequest
0 голосов
/ 05 июня 2019

Я использую библиотеку Microsoft Graph API (C #) и задаюсь вопросом, сталкивался ли кто-нибудь с этим:
Время от времени многие из моих API API вызывают тайм-ауты.
Это может произойти с любым вызовом API, от получения текущего профиля пользователя до получения документов sharepoint и т. Д. Я пытался обновить Microsoft Graph API и зависимые пакеты Nuget до последних версий, но это не помогает.

Для пояснения, это приложение является консольным приложением Windows. На стороне Azure оно зарегистрировано как собственное приложение. Как тестовое приложение, это однопоточное приложение. Нет параллелизма, участвуют условия гонки. Логика кода так же проста, как

  1. Пользователь входит в систему.
  2. Программа выполняет вызов API Graph (показанный в примере 1), чтобы получить профиль пользователя, и время ожидания этого вызова API.

например, 1.

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

например 2.

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

Симптом через одну или две минуты выдает исключение AggregationException (из-за TPL), которое включает исключение TimeOutException.
Нет несанкционированного исключения.

Я хочу знать, что может быть возможной причиной и как мне этого избежать.


UPDATE: Вот скриншот, когда происходит исключение. 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();

Произошло необработанное исключение типа «Microsoft.Graph.ServiceException» в mscorlib.dll Дополнительная информация: Код: время ожидания

Вот полный стек вызовов

в Microsoft.Graph.HttpProvider.d__19.MoveNext () --- Конец стека трассировки из предыдущего места, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в Microsoft.Graph.HttpProvider.d__18.MoveNext () --- Конец стека трассировки из предыдущего места, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в Microsoft.Graph.BaseRequest.d__35.MoveNext () --- Конец стека трассировки из предыдущего места, где было сгенерировано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в 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 (Task задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task задача) в Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException (Task задача) в SharePointConsoleApp.Program.Main (String [] args) в D: \ TestProjects \ SharePointConsoleApp \ Program.cs: строка 50 в System.AppDomain._nExecuteAssembly (сборка RuntimeAssembly, String [] аргументы) в System.AppDomain.ExecuteAssembly (String assemblyFile, Свидетельство сборкиSecurity, String [] args) в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
в System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта)
в System.Threading.ExecutionContext.RunInternal (ExecutionContext executeContext, ContextCallback обратный вызов, состояние объекта, логическое значение preserveSyncCtx) в System.Threading.ExecutionContext.Run (ExecutionContext executeContext, ContextCallback обратный вызов, состояние объекта, логическое значение preserveSyncCtx) вSystem.Threading.ExecutionContext.Run (ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Threading.ThreadHelper.ThreadStart ()

Ответы [ 2 ]

0 голосов
/ 17 июля 2019

Может быть, ответ (полезная нагрузка), который вы получаете, очень велик, хотя время обработки запроса истекло?У меня часто возникала эта проблема, когда я возился с графиком API, поэтому я использовал pagination , чтобы ограничить размер / количество отправляемых им элементов.

0 голосов
/ 16 июля 2019

Прежде всего, если это приложение с взаимодействием с пользователем, вы никогда не должны блокировать (.Wait() или .Result) вызовы в главном потоке, это заблокирует ваше приложение для дальнейшего взаимодействия с пользователем.

Итак, вам нужно начать с использования асинхронного кода, это пример асинхронного обработчика Button_Click. Он выдаст вам предупреждение, но, похоже, это один из вариантов использования асинхронной пустоты.

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;
}

Несколько дней назад я нашел красивое видео о распространенных ошибках асинхронности / ожидания

Похоже, вы говорите о консольном приложении, работающем в 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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...