K1llMan / Yandex.Music.Api

Yandex.Music API (Unofficial) for .Net
GNU General Public License v3.0
91 stars 19 forks source link

Зависают приложения Windows Forms #15

Closed shuryak closed 1 year ago

shuryak commented 1 year ago

Использование библиотеки в приложениях Windows Forms (не важно, какой версии .NET Framework или даже .NET / .NET Core) ведёт к их вечному зависанию при вызове любого метода, обращающегося к API Яндекс Музыки в любом месте приложения (в консольных программах библиотека работает нормально).

Например, следующий код, помещённый в конструктор формы вообще не даст отобразить форму, и приложение намертво зависнет:

YandexMusicClient api = new();
MessageBox.Show(api.GetAuthQRLink());
shuryak commented 1 year ago

Оказалось, вызов НЕ любого метода заставляет приложение зависнуть. Так, например, асинхронные методы Track.GetAsync и Search.TrackAsync работают, а их синхронные версии — нет. При этом, например, метод User.GetAuthQRLink зависает и в синхронном, и в асинхронном вариантах.

shuryak commented 1 year ago

Получил интересный результат в интерактивном C# при дебаге, не знаю имеет ли это отношение к проблеме:

image

shuryak commented 1 year ago
Target process has exited during evaluation of instance method System.Threading.Tasks.Task`1 ::get_Result() with actual parameters
System.Threading.Tasks.Task`1[Yandex.Music.Api.Models.Common.YResponse`1[Yandex.Music.Api.Models.Queue.YQueueItemsContainer]]. This may possibly happen due to StackOverflowException.
This method has been disabled to evaluate
shuryak commented 1 year ago

Видимо, проблема где-то здесь. Как раз здесь условная компиляция. Возможно, для Windows Forms, по какой-то причине, client вообще не компилируется.

image

shuryak commented 1 year ago

Но тогда получается совсем странно. Для каких-то методов работает, а для каких-то — нет, хотя все они проходят через этот код.

shuryak commented 1 year ago

На самом деле работают почти все методы, кроме тех, что связаны с получением объектов для авторизации, таких как QR-коды. Потому что, видимо, данные для их получения извлекаются из HTML-содержимого или вроде того...

shuryak commented 1 year ago

Таким образом проблема в методе GetCsrfTokenAsync(), в нём вызывается GetResponseAsync(), который, в свою очередь, вызывает GetWebResponseAsync() у DefaultRequestProvider. В чём конкретно там заключается проблема — непонятно.

K1llMan commented 1 year ago

Я проверю, возможно, что намудрил с асинхронной цепочкой вызовов. Вообще там сначала должна сессия создаваться для новой авторизации, потом вызываться метод получения объекта для авторизации, например, QR, и потом он должен передаваться в AuthorizeByQR. После этого вызывается получение токена. @martin211 можешь пояснить механизм?

martin211 commented 1 year ago

Если авторизация идет по QR, то сессия создается автоматически. Для других авторизаций, требуется сначала вызвать CreateAuthSession() После подтверждения через приложение, нужно сделать авторизацию и получить токен через GetAccessToken()

shuryak commented 1 year ago

Скорее всего, дело в асинхронности, ведь в консольных приложениях всё отрабатывает.

shuryak commented 1 year ago

В приложениях ASP.NET Core тоже всё отрабатывает. Пока что проблема замечена только в WIndows Forms.

K1llMan commented 1 year ago

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

ghost commented 1 year ago

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

Когда пофиксишь?

K1llMan commented 1 year ago

Когда пофиксишь?

Что пофикшу? И кто ты такой?

K1llMan commented 1 year ago

В версию 1.3.6 добавлены асинхронные методы.