Как ждать, пока другой сервис завершит задание в фоновом режиме, не дожидаясь? - PullRequest
5 голосов
/ 04 апреля 2019

Я создаю ASP.NET Core WebApi, который использует Autodesk Model Derivative API для преобразования файла Revit в другой формат файла.После загрузки файла API-интерфейс Autodesk начинает работать в фоновом режиме и может занять несколько минут, чтобы завершить его работу.

Я хочу отслеживать состояние API-интерфейса Autodesk, чтобы узнать, было ли преобразование выполнено.закончил еще и уведомил пользователя.Я ищу лучший способ следить за состоянием задания, не ожидая, и оставляя запрос зависшим на несколько минут.

Я пытался просто выполнить задачу асинхронно, не ожидая результата.Это работало до того момента, когда я захотел обновить значение в моем контексте базы данных, потому что оно было удалено из-за того, что запрос завершился.

Я также исследовал несколько вариантов реализации фоновых служб, ноне нашел четкого способа сделать это.

public async Task<ActionResult<Response<JobResponse>>> UploadFile(string bucketKey, IFormFile file)
{
    // ....
    // File has been uploaded 
    Response<JobResponse> response
        = await NetworkManager.PostAsync<JobResponse>(URI.Job.Url, JsonConvert.SerializeObject(jobData));

    // The job has been created in the Autodesk API, so I create a record in my own database
    var job = new Job(urn, file.FileName);
    context.Jobs.Add(job);
    await context.SaveChangesAsync();

    // This method is what I want to do in the background 
    MonitorStatus(job);

    return Respond(response);
}

private async Task MonitorStatus(Job job)
{
    bool isDone = false;

    while (!isDone)
    {
        isDone = await IsDone(job.Urn);

        if (!isDone)
            await Task.Delay(10000);
    }

    string guid = await new JobRepository(job).GetGuid();

    // The line underneath throws an error because the context has been disposed
    (await context.Jobs.FindAsync(job.Id)).Finish(guid);
    await context.SaveChangesAsync();

    // ...
    // Notify the user
}

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Перевод файлов в Модель производного API сводится к двум основным конечным точкам:

  • POST job для запуска перевода и
  • GET manifest для получения манифеста перевода (включая его статус, пока перевод еще выполняется)

Если вы делаете HTTP-запросы самостоятельно, вы можете просто опрашивать манифест, пока не увидите, что перевод завершен.

Если вы используете Forge .NET SDK , вы можете запустить перевод с помощью метода Translate и опросить результаты с помощью метода GetManifest .

1 голос
/ 05 апреля 2019

В итоге я использовал Webhook из Autodesk Forge, который вызывает конечную точку, которая уведомляет пользователя о том, что преобразование завершено.Этот веб-крючок содержит тело с информацией о том, какое задание было выполнено, поэтому я могу соответствующим образом обновить базу данных.

Этот веб-крючок устраняет необходимость в моем методе MonitorStatus(job).

https://forge.autodesk.com/en/docs/webhooks/v1/tutorials/create-a-hook-model-derivative/

...