I am working on an app which records input from microphones to .wav files using NAudio. My Recorder class uses a BackgroundWorker to record. I start recording and keep doing so until either 10s have elapsed, or the user requested a cancellation. This works fine in most cases, except one. In debug, when I unplug the recording device midway through, things go nowhere. I expected that the problem would be caught in the BackgroundWorkedCompletedTask method by the case where the worker completion event args is e.Error (which works fine if I throw any standard exception), but this is not the case. When I select "Break All", it brings me to the BackgroundWorkedCompletedTask method, on the line this.waveIn.StopRecording();
, and all properties on the object appear as Cannot evaluate expression because a native frame is on top of the call stack.
I assume this has to do with NAudio using un-managed code to interact with the device; what I would appreciate is any guidance or suggestions on how one should deal with situations like this. It doesn't seem like a try/catch block will do the job here, so where should I deal with it? Thanks in advance for any help.
For completeness, here are the 2 relevant parts of code involved:
private void RecordUsingBackgroundWorker(BackgroundWorker worker)
{
var devices = this.FindDevices();
var deviceIndex = devices.IndexOf(this.requestedDevice);
var waveIn = new WaveIn(WaveCallbackInfo.FunctionCallback());
waveIn.DeviceNumber = deviceIndex;
waveIn.WaveFormat = new WaveFormat(8000, 1);
this.waveIn = waveIn;
this.waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(DataIsAvailable);
var filename = Globals.ThisAddIn.CommentFilePath;
this.waveFileWriter = new WaveFileWriter(filename, waveIn.WaveFormat);
var stopwatch = new Stopwatch();
stopwatch.Start();
this.waveIn.StartRecording();
while (stopwatch.ElapsedMilliseconds < 10000 && !worker.CancellationPending)
{
}
}
Here is the code that executes when work is done:
private void BackgroundWorkedCompletedTask(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
}
else if (e.Error != null)
{
}
if (this.waveIn != null)
{
this.waveIn.StopRecording();
}
this.CleanUpAfterStoppedRecording();
this.IsRecording = false;
if (this.RecorderBusyRecordingChanged != null)
{
this.RecorderBusyRecordingChanged(this, new RecorderBusyEventArgs(false));
}
}