关于使用NAudio麦克风扬声器组件造成WPF应用程序卡死问题跟踪及异步队列的实现

  • 关于使用NAudio麦克风扬声器组件造成WPF应用程序卡死问题跟踪及异步队列的实现已关闭评论
  • 146 次浏览
  • A+
所属分类:.NET技术
摘要

由于WPF应用程序出现卡死的情况,特记录一下问题的跟踪情况1、多次进行NAudio事件注册,没有启用注销再注册的方式,造成应用程序CPU过高

由于WPF应用程序出现卡死的情况,特记录一下问题的跟踪情况

1、多次进行NAudio事件注册,没有启用注销再注册的方式,造成应用程序CPU过高

private AudioNotificationClient audioNotification = new AudioNotificationClient();

audioNotification.DeviceStateChanged += AudioNotification_DeviceStateChanged;

private MMDeviceEnumerator _mmDeviceEnumerator = new MMDeviceEnumerator();

_mmDeviceEnumerator.RegisterEndpointNotificationCallback(audioNotification);

缺少注销

_mmDeviceEnumerator.UnregisterEndpointNotificationCallback(audioNotification);

2、事件注册同时麦克风设备状态发生改变DeviceStateChanged,造成线程死锁

可以使用异步队列,把事件的注册,注销与DeviceStateChanged执行逻辑都放进异步队列,保证不会出现同时执行的情况。

异步队列的实现:

  /// <summary>     /// 异步任务队列     /// </summary>     public class AsyncTaskQueue : IDisposable     {         private bool _isDisposed;         private readonly ConcurrentQueue<AwaitableTask> _queue = new ConcurrentQueue<AwaitableTask>();         private Thread _thread;         private AutoResetEvent _autoResetEvent;          /// <summary>         /// 异步任务队列         /// </summary>         public AsyncTaskQueue()         {             _autoResetEvent = new AutoResetEvent(false);             _thread = new Thread(InternalRuning) {IsBackground = true};             _thread.Start();         }          private bool TryGetNextTask(out AwaitableTask task)         {             task = null;             while (_queue.Count > 0)             {                 if (_queue.TryDequeue(out task) && (!AutoCancelPreviousTask || _queue.Count == 0)) return true;                 task.Cancel();             }             return false;         }          private AwaitableTask PenddingTask(AwaitableTask task)         {             lock (_queue)             {                 Debug.Assert(task != null);                 _queue.Enqueue(task);                 _autoResetEvent.Set();             }             return task;         }          private void InternalRuning()         {             while (!_isDisposed)             {                 if (_queue.Count == 0)                 {                     _autoResetEvent.WaitOne();                 }                 while (TryGetNextTask(out var task))                 {                     if (task.IsCancel) continue;                      if (UseSingleThread)                     {                         task.RunSynchronously();                     }                     else                     {                         task.Start();                     }                 }             }         }          /// <summary>         /// 是否使用单线程完成任务.         /// </summary>         public bool UseSingleThread { get; set; } = true;          /// <summary>         /// 自动取消以前的任务。         /// </summary>         public bool AutoCancelPreviousTask { get; set; } = false;          /// <summary>         /// 执行任务         /// </summary>         /// <param name="action"></param>         /// <returns></returns>         public AwaitableTask Run(Action action)             => PenddingTask(new AwaitableTask(new Task(action, new CancellationToken(false))));          /// <summary>         /// 执行任务         /// </summary>         /// <typeparam name="TResult"></typeparam>         /// <param name="function"></param>         /// <returns></returns>         public AwaitableTask<TResult> Run<TResult>(Func<TResult> function)             => (AwaitableTask<TResult>) PenddingTask(new AwaitableTask<TResult>(new Task<TResult>(function)));           /// <inheritdoc />         public void Dispose()         {             Dispose(true);             GC.SuppressFinalize(this);         }                  /// <summary>         /// 析构任务队列         /// </summary>         ~AsyncTaskQueue() => Dispose(false);          private void Dispose(bool disposing)         {             if (_isDisposed) return;             if (disposing)             {                 _autoResetEvent.Dispose();             }             _thread = null;             _autoResetEvent = null;             _isDisposed = true;         }          /// <summary>         /// 可等待的任务         /// </summary>         public class AwaitableTask         {             private readonly Task _task;              /// <summary>             /// 初始化可等待的任务。             /// </summary>             /// <param name="task"></param>             public AwaitableTask(Task task) => _task = task;              /// <summary>             /// 任务的Id             /// </summary>             public int TaskId => _task.Id;              /// <summary>             /// 任务是否取消             /// </summary>             public bool IsCancel { get; private set; }              /// <summary>             /// 开始任务             /// </summary>             public void Start() => _task.Start();              /// <summary>             /// 同步执行开始任务             /// </summary>             public void RunSynchronously() => _task.RunSynchronously();              /// <summary>             /// 取消任务             /// </summary>             public void Cancel() => IsCancel = true;              /// <summary>             /// 获取任务等待器             /// </summary>             /// <returns></returns>             public TaskAwaiter GetAwaiter() => new TaskAwaiter(this);              /// <summary>Provides an object that waits for the completion of an asynchronous task. </summary>             [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]             public struct TaskAwaiter : INotifyCompletion             {                 private readonly AwaitableTask _task;                  /// <summary>                 /// 任务等待器                 /// </summary>                 /// <param name="awaitableTask"></param>                 public TaskAwaiter(AwaitableTask awaitableTask) => _task = awaitableTask;                  /// <summary>                 /// 任务是否完成.                 /// </summary>                 public bool IsCompleted => _task._task.IsCompleted;                  /// <inheritdoc />                 public void OnCompleted(Action continuation)                 {                     var This = this;                     _task._task.ContinueWith(t =>                     {                         if (!This._task.IsCancel) continuation?.Invoke();                     });                 }                 /// <summary>                 /// 获取任务结果                 /// </summary>                 public void GetResult() => _task._task.Wait();             }         }          /// <summary>         /// 可等待的任务         /// </summary>         /// <typeparam name="TResult"></typeparam>         public class AwaitableTask<TResult> : AwaitableTask         {             /// <summary>             /// 初始化可等待的任务             /// </summary>             /// <param name="task">需要执行的任务</param>             public AwaitableTask(Task<TResult> task) : base(task) => _task = task;               private readonly Task<TResult> _task;              /// <summary>             /// 获取任务等待器             /// </summary>             /// <returns></returns>             public new TaskAwaiter GetAwaiter() => new TaskAwaiter(this);              /// <summary>             /// 任务等待器             /// </summary>             [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]             public new struct TaskAwaiter : INotifyCompletion             {                 private readonly AwaitableTask<TResult> _task;                  /// <summary>                 /// 初始化任务等待器                 /// </summary>                 /// <param name="awaitableTask"></param>                 public TaskAwaiter(AwaitableTask<TResult> awaitableTask) => _task = awaitableTask;                  /// <summary>                 /// 任务是否已完成。                 /// </summary>                 public bool IsCompleted => _task._task.IsCompleted;                  /// <inheritdoc />                 public void OnCompleted(Action continuation)                 {                     var This = this;                     _task._task.ContinueWith(t =>                     {                         if (!This._task.IsCancel) continuation?.Invoke();                     });                 }                  /// <summary>                 /// 获取任务结果。                 /// </summary>                 /// <returns></returns>                 public TResult GetResult() => _task._task.Result;             }         }