Cant Close Form...

Dec 4, 2009 at 8:57 PM

Hi, thanks for the wrapper, i was using another package, but this is really all i need

im doing wavein, right to waveout, works perfectly (capture to live play)

but if i do
wavin.STOP()  in form_closing, it deadlocks on the bufferMaintainerThread.Join

im sure its because the form is desposing, but i want to stop the wavein..
if i do nothing, it does exit, not clean, but windows im sure cleans up
since the application is terminated

Coordinator
Jan 5, 2010 at 5:01 AM
Edited Jan 5, 2010 at 7:38 PM

Nice to hear that is mostly working.  And, sorry I took so long to reply.

I was having a similar intermittent problem, and I'm pretty sure my issue is due to the way the OS is freeing the buffers.  In rare circumstances, the OS fails to release the buffer correctly.

If you are having the problem EVERY time you hit stop, you are probably hitting a race-condition that causes a deadlock.  Make sure that you are locking on the WaveOut object before you dispose and while writing to it.

I have uploaded a demo project for you and others to evaluate.

Here is the code:

namespace EchoDemo
{
    using System;
    using System.IO;
    using System.Windows.Forms;
    using WinMM;

    public partial class MainView : Form
    {
        private object actionLock = new object();
        private WaveIn waveIn;
        private WaveOut waveOut;

        public MainView()
        {
            InitializeComponent();
            
            WaveFormat format = WaveFormat.Pcm44Khz16BitMono;

            this.waveIn = new WaveIn(WaveIn.WaveInMapperDeviceId);
            this.waveOut = new WaveOut(WaveOut.WaveOutMapperDeviceId);
            this.waveOut.Open(format);
            this.waveIn.BufferQueueSize = 200;
            this.waveIn.BufferSize = 64;
            this.waveIn.DataReady += new EventHandler<DataReadyEventArgs>(this.WaveIn_DataReady);
            this.waveIn.Open(format);
            this.waveIn.Start();
        }

        private void WaveIn_DataReady(object sender, DataReadyEventArgs e)
        {
            lock (this.actionLock)
            {
                if (this.waveOut != null)
                {
                    this.waveOut.Write(e.Data);
                }
            }
        }

        private void MainView_FormClosed(object sender, FormClosedEventArgs e)
        {
            lock (this.actionLock)
            {
                this.waveIn.Dispose();
                this.waveIn = null;
            }

            lock (this.actionLock)
            {
                this.waveOut.Dispose();
                this.waveOut = null;
            }
        }
    }
}

Jan 9, 2010 at 9:36 PM

this doesnt help

it still locks SOILD when trying to JOIN the threads, when CLOSING the form...

can i send you my project? its tiny... it looks for a specific device.. but u can have it open any wavein device

 

mitch

Coordinator
Jan 12, 2010 at 3:48 AM
Edited Jan 14, 2010 at 2:04 AM

sure thing.  I'll take a look.

give me a URL or your email.

May 16, 2010 at 11:02 PM

Close() waveIn and waveOut before Dispose(). It solves the problem

May 16, 2010 at 11:20 PM

Doesn’t make any difference…

I close both.. and still hangs on form close

In fact it hangs in wavein.close()

mitch

May 27, 2010 at 9:30 PM
Here is my version of application closing which made sample above to close without hang.

private void MainView_FormClosing(object sender, FormClosingEventArgs e) {
waveIn.Close();
waveOut.Close();
lock (this.actionLock) { this.waveIn.Dispose(); this.waveIn = null; } lock (this.actionLock) { this.waveOut.Dispose(); this.waveOut = null; } }

 

May 29, 2010 at 6:18 PM

No difference still hangs solid

Remember, when you close the form you have to be capturing

If you give me a place I can put the program. Its so tiny… just a few lines to test prof of concept

It always hangs in wavein.close() at the stop()

this.bufferMaintainerThread.Join();

mitch

May 29, 2010 at 6:23 PM

To note, when I close the form OUTSIDE of the IDE

See the end of this message for details on invoking

just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************

System.ObjectDisposedException: Safe handle has been closed

at System.StubHelpers.StubHelpers.SafeHandleC2NHelper(Object pThis, IntPtr pCleanupWorkList)

at WinMM.NativeMethods.waveInClose(WaveInSafeHandle hwi)

at WinMM.WaveInSafeHandle.ReleaseHandle() in C:\Users\mitchjs\Documents\Visual Studio 2008\Projects\winmm capture\WinMM.Net\WaveInSafeHandle.cs:line 62

at System.Runtime.InteropServices.SafeHandle.InternalDispose()

at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)

at WinMM.WaveIn.Close() in C:\Users\mitchjs\Documents\Visual Studio 2008\Projects\winmm capture\WinMM.Net\WaveIn.cs:line 304

at Test3.Form1.Form1_FormClosed(Object sender, FormClosedEventArgs e) in C:\Users\mitchjs\Documents\Visual Studio 2008\Projects\winmm capture\Test3\Form1.cs:line 66

at System.Windows.Forms.Form.WmClose(Message& m)

at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Jun 1, 2010 at 8:56 AM
mitchjs, send to me your program to 3i_cy at anthial5.yi.org
Mar 15, 2011 at 12:35 PM

Did you ever figure this out, by any chance?

Thanks for your time!

Mar 15, 2011 at 1:39 PM

Got it working.

 

Moved all  "new"s and "Open()"s to the constructor.

Moved all the "Close()"s to the destructor

this.waveIn.Close()
this.waveOut.Close()

Called 

this.waveIn.Start(); in start()
and
this.waveIn.Stop(); in stop()