Правильный способ использования библиотеки asyn c с ASP .NET / MVC / REST - PullRequest
1 голос
/ 01 февраля 2020

У меня есть asyn c Библиотека для обработки аудиофайлов. Кроме того, я хочу предложить эти методы через отдых. Поэтому я сделал MVC проект WebApi. Для запуска библиотеки требуется некоторое время, поэтому я добавил класс, который предлагает способ инициализации и предоставляет основной объект библиотеки.

public static class MusicHandler
{
    public static MusicCapture.MusicCapture MusicCapture;
    public static void init()
    {
        MusicCapture = new MusicCapture.MusicCapture("D:\\Temp", "D:\\test", "E:\\FingerPrintDB2.ss");
        MusicCapture.Start();
    }
}

Я запускаю его в Application_Start ()

protected void Application_Start()
{
    MusicHandler.init();
}

Теперь, когда мой метод init содержит несколько асин c вызовов, подобных этому:

var hashedFingerprints = command.Hash().Result;

Программа просто пропустит эти строки. Они не исполняются за все, что я могу сказать. То же самое происходит, когда я вызываю любой из объектов asyn c методами из моих конечных точек REST. Когда я запускаю библиотеку не из ASP .NET / MVC, код работает безупречно.

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

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 01 февраля 2020

Итак, если я понимаю, вы хотите запустить что-то, называемое MusicHandler, для запуска которого требуется некоторое время. Как только он загрузится, связь с вашей системой будет осуществляться через HTTP-вызовы RESTful.

В вашем MusicHandler вы можете иметь флаг, указывающий, закончилась ли загрузка.

public static class MusicHandler
{
    public static MusicCapture.MusicCapture MusicCapture;
    public static bool Initialized {get;} = False;
    public static void init()
    {
        MusicCapture = new MusicCapture.MusicCapture("D:\\Temp", "D:\\test", "E:\\FingerPrintDB2.ss");
        MusicCapture.Start();
        Initialized = true;
    }
}

Затем в вашем MVC Контроллер, вы можете проверить этот флаг и вернуть ошибку, если инициализация не завершена.

Таким образом, вам не нужно беспокоиться о том, чтобы быть async до самого верха.

Но я удивлен, что вы вообще используете application_start ... разместите его, используя kestrel, и выполните эту настройку в program.cs или где-то еще, где вы можете быть асин c на самом верху.

0 голосов
/ 01 февраля 2020

Я понял мою проблему, она была двоякой.

  1. Ошибка при запуске моей библиотеки была ошибка в библиотеке, которая привела к исключению, которое не всплыло. Мне удалось смягчить эту ошибку. Асин c вызовы при запуске с приложением MVC с .Result внутри, кажется, на самом деле не проблема.

  2. Мои сбои REST-вызовов на асин c могут быть исправлены с помощью изменив методы остальных контроллеров на asyn c. Я никогда бы не подумал, что это возможно, но я нашел здесь пример: https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

// GET api/music
public async System.Threading.Tasks.Task<string> GetAsync()
{
    string result = await MusicHandler.MusicCapture.DetectAsync(5);
    Console.WriteLine("Server returning: " + result);
    return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...