Is it safe to dispose WaveIn and WaveOut right after stopping them, and not in the event handlers of WaveIn.RecordingStopped and WaveOut.PlaybackStopped? Like this:
MyWaveIn.StopRecording();
MyWaveIn.Dispose();
MyWaveIn = null;
And:
MyWaveOut.Stop();
MyWaveOut.Dispose();
MyWaveOut = null;
If WaveIn / WaveOut stopped due to an error, or if the playback stopped because the file being played reach its end, I will dispose them in the event handlers. I'm asking just about the situation where I stop them explicitly.
I generally recommend disposing in the PlaybackStopped event handler, but most soundcard drivers seem perfectly happy with you disposing while playback or recording is still in progress (under the hood you're just calling the waveOutClose or waveInClose windows API).
Related
I am getting the above mentioned exception in PointerPressed that too only in the case of MFC application hosted using XAML Islands. In normal UWP application it is working fine. Essentially no other Pointer events are fired in this scenario (Released, Canceled, CaptureLost,Exited etc) but we need to handle some UI changes in PointerReleased.
Kindly suggest any workarounds for the same.
When responding to an event in a textbox using C++/winrt I need to use ScrollViewer.ChangeView(). Trouble is, nothing happens when the call executes and I expect that is because at that moment the code is in the wrong thread; I have read this is the cause for lack of visible results from ChangeView(). It appears that the proper course is to use CoreDispatcher.RunAsync to update the scroller on the UI thread. The example code for this is provided only in C# and managed C++, however, and it is a tricky matter to figure out how this would look in normal C++. At any rate, I am not getting it. Does anyone have an example of the proper way to call a method on the UI thread in C++/winrt? Thanks.
[UPDATE:] I have found another method that seems to work, which I will show here, though I am still interested in an answer to the above. The other method is to create an IAsyncOperation that boils down to this:
IAsyncOperation<bool> ScrollIt(h,v, zoom){
co_await m_scroll_viewer.ChangeView(h,v,zoom);
}
The documentation entry Concurrency and asynchronous operations with C++/WinRT: Programming with thread affinity in mind explains, how to control, which thread runs certain code. This is particularly helpful in context of asynchronous functions.
C++/WinRT provides helpers winrt::resume_background() and winrt::resume_foreground(). co_await-ing either one switches to the respective thread (either a background thread, or the thread associated with the dispatcher of a control).
The following code illustrates the usage:
IAsyncOperation<bool> ScrollIt(h, v, zoom){
co_await winrt::resume_background();
// Do compute-bound work here.
// Switch to the foreground thread associated with m_scroll_viewer.
co_await winrt::resume_foreground(m_scroll_viewer.Dispatcher());
// Execute GUI-related code
m_scroll_viewer.ChangeView(h, v, zoom);
// Optionally switch back to a background thread.
// Return an appropriate value.
co_return {};
}
I once read in a tutorial (unfortunately, I can't find where), that if I want to play several audio files, and use WaveOut, I should dispose the last WaveOut object before calling the Init method again. If not, I will get an error. However, I didn't dispose the objects, and everything works. I did this:
Mp3FileReader reader_1 = new Mp3FileReader("1.mp3");
Mp3FileReader reader_2 = new Mp3FileReader("2.mp3");
WaveOut WaveOutDevice = new WaveOut();
WaveOutDevice.Init(reader_1);
WaveOutDevice.Play();
and after a while, playing a second file:
WaveOutDevice.Init(reader_2);
WaveOutDevice.Play();
So I just want to be sure that I'm doing the right thing.
WaveOut was initially designed for Init to only be called a single time. In some circumstances it may work, but I'd recommend creating a new instance of WaveOut to play your next sound.
I am using a system.timer in a Windows Service to run a process that usually exceeds the timer's interval. I am trying to keep the timer from firing the same code more than once, a known issue with system.timers.
What I want: The timer runs my code, but the timer "pauses" to wait until the code is completed before resuming ticks.
I have two problems:
The way system.timers work is that the timer will create a race condition on you by launching new redundant threads of the same code and pile them up on you if the has not completed by the time the timer's interval has elapsed.
I would start/stop the timer to keep this from happening, but with a System.Timers.Timer, once you stop the timer for the processing to complete, it never comes back - I have never been able to restart a timer once it has been stopped, it has been destroyed and likely collected. Enabling/disabling is the same exact thing as start/stop with same results.
How on earth do you keep a system.timer from launching new redundant threads of the same code if the process has not completed by the time the timer's interval has lapsed? Obviously, starting/stopping (enabling/disabling) the timer is NOT a solution, as it doesn't work.
Help!
Start your timer when it needs to start, kick off another thread to do the work after which the timer can be stopped. The timer won't care if the thread completed or ran away with the prize money. Use Task Parallel Library (TPL) for the most effective usage.
The Start and Stop methods on the Timer do actually work in a Windows service.
I have multiple production services which use code that do that, except my code is written in C#.
However, make sure you are using the System.Timers.Timer and not the Windows.Forms.Timer
Here's a quick example of C# / pseudocode of what my services look like.
// this is the OnStart() event which fires when windows svc is started
private void OnStart()
{
// start your timer here.
MainTimer.Start();
}
private void ElapsedEventHandler()
{
try
{
// Stop the timer, first thing so the problem of another timer
// entering this code does not occur
MainTimer.Stop();
//Do work here...
}
catch (Exception ex)
{
// if you need to handle any exceptions - write to log etc.
}
finally
{
MainTimer.Start();
// finally clause always runs and will insure
// your timer is always restarted.
}
}
I have hosted a WCF service in windows service. I have console app for which I added a WCF service reference and generated Client for it.
I can make Sync call to the service,but Async call doesn't seem to work. If i attach server process it doesn't hit the service at all.
client= new ServiceClient();
client.DoSomething();//Works fine
client.DoSomethingAsync()//Doesnot work
Is this a known problem?
The asynccall will probably be started in a background workerthread. So what could be happening is that your async thread is dieing out because the foreground thread has finished it's processing.
Unless you have some logic after you make this call to wait for the reponse, or continue with some other work on your main thread, the background thread may not have the time to get created before the application exits.
This can be easily tested by adding Thread.Sleep after the async call.
client.DoSomethingAsync();
Thread.Sleep(1000);
A symptom of this happening is that your service starts / stops unexpectedly and windows throws an error.
When you generated the client, did you tick the box to specify "Generate asynchronous operations"?
From the code posted, i'm assuming you have not set up handlers to deal with the response from the async method. You'll need something like the example at the bottom of this msdn post where you use AddHanlder to handle the response.
Something like the below before you make the async call:
AddHandler client.DoSomethingCompleted, AddressOf DoSomethingCallback
With a method to deal with the outome:
Private Shared Sub DoSomethingCallback(ByVal sender As Object, ByVal e As DoSomethingCompletedEventArgs)
'Do something with e.Result
MsgBox e.Result
End Sub
If you have a call to
client.DoSomethingAsync()//Doesnot work
then did you specify a handler for the callback completed event??
public event DoSomethingCompletedEventHandler DoSomethingCompleted;
What happens is that the async call goes off, but how would it send you back any results?? You'll need to provide a handler method for that - hook it up to the DoSomethingCompleted event handler! In that method, you'll get the results of the async call and you can do with them whatever you need to do.
Marc