I am working on a really fun project. I have written much of a program that lets you use a RockBand or GuitarHero drum kit to play drum sounds on your PC, record, playback, ect. I have decided conclusively as I add features I need more than just a gui thread calling async play sound methods. I need extensive threading here and for the most part I know what to do.

But I have a Metronome class that uses async media timer and playsound methods. but still has trouble being accurate if something else on the form slows down the message loop. So I have started a new thread that uses Application.Run() to start that thread with its own message loop. then creates the timer class, starts it and hooks up an event. then in the event it calls the playsoundAsync method.

So now I have 2 problems, How do I safely change the timer objects Interval property from the GUI thread? and then How do I safely stop this type of thread? the standard while loop practice is useless here because I am using a MessageLoop to process events.

I have most often used threading to do some finite task that will return when its done. This is a new practice for me using threads to insure an accurate "on-beat" playing of audio.

I have lots of code bouncing around in my head, I just want some insight before I make a mess. Searching the net has come up with frustrating results, Conflicting forum posts, and indirect answers.


Recommended Answers

All 2 Replies

Hmmm, interesting, so basically you need that beat acurate in time (the metronome).
-First, if the time interval of the timer can be changed (I didn't work with timers too much) then you must make a delegade from the GUI thread pointed to the procedure that sets the interval. If you are just sick of delegades and delegades... use this code (although I don't know how safe it is):

CheckForIllegalCrossThreadCalls = false;

If the thread loop forever just let it loop as long as you have a boolean variable true. When you acces the variable from the GUI thead and make it false, the loop is over.

-Second, I wouldn't necessary use a timer. You can have an infinite loop with a delay in it. It can be variable.

bool keepRunning = true;
int milisecondDelay = 1000;
//do your job here

And, if it's not accurate, think about this: maybe you can bind your Metronome with Windows time which is always accurate... if you know what I mean.

Hope this helps... and I was not confusing
P.S.: I am myself a musician and work with lot of music editing programs so I understand what kind of program you are trying to do. Nice :)

Unfortunately because I am using events I have to use the windows message loop in my thread. so the while(true) loop concept doesn't apply here. I tried using thread.abort() but it doesn't stop a thread with a message loop. I come to the conclusion that i need to find a way to call Application.ExitThread() from the thread I want to stop. and I couldn't figure out how to do that because control.Invoke always invokes onto the the GUI thread. i can't seem to figure out how to invoke a method onto a background loop. I found out quick you can crash visual studio easy with application.exitThread though :)

I need to buy a book on this, there is very little online material around this matter and trial and error isn't all its cracked up tobe these days.

either way, the program is coming along quit nicely and its almost ready to make an appearance.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.