Я только начинаю работать с CSCore и возвращаюсь к C# после большого количества C++. Вот тестовая программа, которая перечисляет аудиосеансы диспетчера аудиосеансов по умолчанию и прикрепляет пустой обработчик событий к каждому из них:
using System;
using CSCore.CoreAudioAPI;
class Program
{
static void Main(string[] args)
{
using (var enumerator = new MMDeviceEnumerator())
using (var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia))
using (var sessionManager = AudioSessionManager2.FromMMDevice(device))
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
foreach (var control in sessionEnumerator)
{
var control2 = control.QueryInterface<AudioSessionControl2>();
RegisterAudioSession(control2);
}
}
Console.WriteLine("Waiting...");
Console.ReadKey();
}
static void RegisterAudioSession(AudioSessionControl2 session)
{
if (session.Process != null)
{
var events = new AudioSessionEvents();
session.RegisterAudioSessionNotification(events);
}
}
}
Я ожидаю, что смогу без проблем изменить громкость своего компьютера во время работы этой программы. Однако, если вы попробуете это сделать, программа вылетит из-за нарушения прав доступа в машинном коде. Вот трассировка стека:
> AudioSes.dll!CLockedList<ATL::CComPtr<IAudioSessionEvents>,0,1>::ForEachEntry() Unknown
AudioSes.dll!CAudioSessionControl::OnAudioSessionEvent() Unknown
AudioSes.dll!CAudioSessionControl::CAudioSessionNotificationDelegator::OnMediaNotification(struct MEDIA_NOTIFICATION_BLOCK *) Unknown
MMDevAPI.dll!CMediaNotifications::OnMediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *) Unknown
MMDevAPI.dll!CMediaNotifications::MediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *,void *) Unknown
ntdll.dll!TppSimplepExecuteCallback() Unknown
ntdll.dll!TppWorkerThread() Unknown
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
Сбой не происходит, если вы удалите вызов RegisterAudioSessionNotification
.
Сбой по-прежнему происходит, если вы регистрируете непустой обработчик событий.
Я попытался переместить Console.ReadKey();
в блок using на случай, если необходимый ресурс был удален, но сбой не исчез.
Я искал повсюду объяснение и решение. На странице CSCore github нет соответствующих открытых проблем. Я где-то читал, что сбои в нативном коде часто бывают вызваны неправильными подписями в сборках-обертках. Я сравнил все методы CSCore IAudioSessionEvents с собственными методами IAudioSessionEvents (перечислены здесь), но не обнаружил явных несоответствий.
Эта ошибка Firefox — единственная ссылка, которую я нашел в Интернете на эта конкретная трассировка стека, и она была разрешена. По-видимому, это было решено в Flash Player 19.0.0.159, но, насколько мне известно, этот источник недоступен для прочтения.
Я пропустил ошибку в своем коде или это ошибка в CSCore?