Вызов процесса асинхронно через WebAPI - PullRequest
0 голосов
/ 22 ноября 2018

Я нахожусь в ситуации, когда мне нужно вызвать exe-процесс через конечную точку API (запустить и забыть).Тем не менее, exe-файл, который я назову, является долгосрочным, но мне нужно дождаться его завершения, чтобы выполнить дальнейшие коды.Это произойдет в фоновом режиме, и клиент не должен ждать этого.Когда я пытаюсь код ниже, вызов ждет завершения exe-процесса.Я также попытался сделать метод "асинхронным", но все еще тот же результат.

    [HttpPost]
    public async Task<bool> ToggleCarWeaverService(string command)
    {
        try
        {
            var fileName = @"SomeExe.exe";
            await _service.RunProcessAsync(command, fileName);
            return true;

        }
        catch (Exception ex)
        {
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
    }


    public Task<int> RunProcessAsync(string command, string fileName)
    {
        // Use ProcessStartInfo class
        ProcessStartInfo startInfo = new ProcessStartInfo
        {
            CreateNoWindow = false,
            UseShellExecute = true,
            FileName = fileName,
            WindowStyle = ProcessWindowStyle.Normal,
            Arguments = command
        };

        try
        {
            var tcs = new TaskCompletionSource<int>();

            var process = new Process
            {
                StartInfo = startInfo,
                EnableRaisingEvents = true
            };

            process.Exited += (sender, args) =>
            {
                tcs.SetResult(process.ExitCode);
                //Do more code
                process.Dispose();

            };

            process.Start();

            return tcs.Task;
        }
        catch (Exception ex)
        {
            // Log error.
            throw ex;
        }
    }

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

Не ждите асинхронной задачи.

Используйте Task.Run для переноса и продолжения

[HttpPost]
public IHttpActionResult ToggleCarWeaverService(string command) {
    Task.Run(async () => {
        var fileName = @"SomeExe.exe";
        await _service.RunProcessAsync(command, fileName);
        //...other code after process finish
    });
    return Ok();
}
0 голосов
/ 22 ноября 2018

Ответы, приведенные здесь, правильно ответят на ваш вопрос, то есть, не ожидая результата, ваш звонок немедленно вернется.Тем не менее, нет никаких гарантий, что этот процесс продолжится.После того, как вы вышли из функции, у вас фактически есть процесс румян, который может или не может завершиться.

У большинства поставщиков облачных решений есть решение для этого (например, Azure WebJobs), или вы можете свернуть свой собственный, используя что-токак HangFire .

0 голосов
/ 22 ноября 2018

Тогда вам вообще не нужно await звонить и, таким образом, изменить линию, на которой вы ожидаете звонка RunProcessAsync, на

_service.RunProcessAsync(command, fileName);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...