I have large WPF application which also uses MEF.
I want to trigger an Audio alert on certain condition and repeat it for the times specified by user. audio file can be .wav or .mp3.
I am making use of SoundPlayer to play the audio.
I am not sure which timer to use for repeat intervals.
I dont want to block UI thread when audio is playing and also want it to be threadsafe.
thanks in advance.
Why not consider using Event Aggregation, which is an implementation of publisher subscriber pattern. Whenever your application encounters a condition where it wants to play audio, it would publish its intensions via the event aggregator.
There would be a listener who listens for these events and would play the correct audio based on the type of the event. If there are multiple requests, the listener may play them in parallel or in a sequence. You can implement the desired threading model within the listener and standard thread-sleep
This way, you get to keep all you audio configuration and logic tucked behind a single module. All the other modules will just ‘tell’ this module what they want to play (and optionally for how long)
On the other hand, unless your application is large enough the above approach would be an overkill
A good write-up on event aggregation
http://codebetter.com/glennblock/2009/02/23/event-aggregation-with-mef-with-and-without-eventaggregator/
Related
I am new to adobe Analytics. I am trying to track form errors that are occurring when the user submitting the form without filling the required fields.
So here what I did was, passed form values to list prop to capture the values. But I am not getting how to implement events to track against these values.
Can anyone please help me with how to implement rules and events in the adobe launch for tracking?
Yes, there are a few ways to do it.
The recommended way is to ask the Front-end team to send an error event that Launch can listen to. It can be done in a few ways. It's considered the best practice to install the adobeDataLayer extension: https://experienceleague.adobe.com/docs/launch/using/extensions-ref/adobe-extension/acdl/overview.html?lang=en
The extension provides ability to use a dataLayer very similar to GTM. Very comfortable.
The other way to do it is ask the devs to send a simple JS customEvent with error details in the detail property of the event.
Launch can natively listen to JS events and gives access to the event object.
Finally, the worst kind of implementation, that should be mostly considered as a hack, is the become visible trigger:
you're supposed to detect the actual error message with this trigger. I suggest not using it since the enters viewport listener is a bit heavy. And it also depends on the DOM structure since you'll have to provide the CSS selector for the error message.
This is not all, surely. You can build your own settimeout polling logic to look for the errors manually, or ask devs to send direct calls, but those are even worse solutions, so I'm not elaborating on them.
Using the Cups c api I am able to see the state of a printer (such as paused, printing, jammed ect.) What I am trying to do now is to listen for, or lock against a change in a printer's state. Ultimately I want a live view of a printers state, but I don't want to have a delay loop spamming cups with printer attribute requests.
I have seen many functions and tags in the source code and documentation that hint towards some kind of event system, but I have been unable to figure out how to utilize it. Any help is welcome, even just pointing me towards the right function.
I used this example in my current implementation to get state information. http://cups-dev.easysw.narkive.com/9RO0OBnZ/how-to-get-printer-status-via-cups-api
It ends up this was a very complex question and involved a lot of work to figure out. The only sane way I found to listen for changes was to use the rss notification system. I would advise against attempting to make your own notification module, I wasted a week of my life trying that (I'm not even sure it is possible anymore). Use the Create-Printer-Subscription with a uri like rss://localhost:8000. You will of course need a listener waiting for the xml data.
I put up an a simple debugging tool I made with java/jna here. Select 2 to set up a subscription, you will need to listen for the data yourself though.
I'm kind of new to Windows Forms. The Windows Forms app I've created is the front-end to a component that does very time-consuming data transformation tasks. The data transformation task emits events which the form subscribes to.
When the form receives an event, it alters the text in a label and calls Refresh() for that label.
When I run the process from the form, it remains responsive and updates the label text for maybe a minute or so. After that, it simply freezes and Windows declares the process 'Unresponsive' until the data transformation is finished, at which time the form unfreezes and the label shows that the data transformation is complete (as expected).
I haven't put the data transformation onto a separate thread - is this the first thing I should try? Can events cross threads? If not, what else should I do?
Yes, threading is where you should be working. Multi threading in WinForms, depending on your version, can be tricky.
If you're using .NET 4.0 or higher, you could be using the Microsoft Task Parallel Library.
Otherwise, there is a good article, here, from C# Corner that covers threading in WinForms applications that I'd suggest as a starting point.
The BackgroundWorker is another option for simplifying threading in WinForms.
I'm building a single window WPF application
In the window is a list items (which are persisted in a database of course)
Periodically I need to start a background task that updates the database from an Atom feed. As each new item is added to the database, the list in the UI must also update to reflect this. I don't want this background task to slow down the UI but at the same time it needs to interact with the UI.
Having read loads of articles and seen lots of simple examples, I am still unsure of the best way to implement this.
What I think maybe I could do is:
On the Window_Loaded event, create a DispatchTimer.
When the Tick event fires, call UpdateDb() method.
UpdateDB() will get the items from the Atom feed and add to the database. As I iterate through each item I will call another method to rebind the list to the database so that it "refreshes".
When all the tasks are finished reset the DispatchTimer ??? (not sure if this can / needs to be / done).
Remember, this is background task so a user could be using the UI at the same time.
How does this sound?
Thanks.
This sounds suboptimal because you're doing database connectivity on the UI thread. When the Tick event fires on the DispatcherTimer, handlers will execute on the UI thread. You need to minimize the amount of work you do on this thread to keep the UI responsive, and you definitely shouldn't be doing IO-bound work on this thread.
I would probably have a data service whose responsibility is to update the database and raise events as changes are made. Your UI layer can attach to these events and marshal to the UI thread to apply changes. To marshal to the UI thread, you just need to call Dispatcher.Invoke.
Regardless of your specific approach, the key is to do as much as you can (including any database access) on a separate thread. Marshal back to the UI thread as late as possible and do as little work as possible on the UI thread.
One other thing to note is that WPF automatically marshals changes to scalar values for you. You only need to marshal changes to collections (adding/removing/replacing items).
Your approach would work.
You'd start the timer when the app loads. For each tick of the timer, you start a thread to update the database. Once the database update has happened, you can call .BeginInvoke() on your UI objects to update the UI on the presentation thread (that will be the only time your UI should be affected).
I'd use a System.Threading.Timer, which will call a specified method at a specified interval on a threadpool thread, so no need to create an additional thread, do your db work with that and marshal back to the ui thread as needed.
WPF Multithreading with BackgroundWorker by Pavan Podila:
The good news is that you really don’t have to write such a component since one is available already: the BackgroundWorker class introduced in .Net Framework 2.0. Programmers who are familiar with WinForms 2.0 may have already used this component. But BackgroundWorker works equally well with WPF because it is completely agnostic to the threading model.
I have developed WPF Application. In that application iam loading 200mb photos to the listbox.After that Iam adding those images to canvas.While adding photos to canvas after sometime (i.e; after adding 10mb images)iam getting Some error like ----
*****The CLR has been unable to transition from COM context 0x10b46f0 to COM context 0x10b4860 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.*****
Is there any way to increase the performance of my application. I need a solution for this problem.
Any Suggestions for this.
Don't load all 200 mb of photos into the listbox all at once on your UI thread. Will the user be looking at 200 mb all at once? It'll take some work on your part, but you're going to need to do some delayed loading of the images from a background thread.
Take a look at this article (Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps), it may help.
This looks like two questions, the first is that you are loading images in a background thread, but not doing it correctly; thus, the COM error. Double check that you are have a STAThread application and that the image loading thread is not interacting with the WPF dispatch thread incorrectly. Here's a discussion MTA vs. STA; however, WPF needs STA, and it's a loosing battle to fight it.
The second question seems to be how should one do this; that is, loading a bunch of images for display. I would look into using a lazy data binding of the ListView and let the virtualizing presenter that's built into is manage the loading/display of the images.
Here's some docs on using a view-model. The viewmodel could coordinate the image load and provide the ListView with a binding source that would automatically get the application working.
A simpler alternative might be to start up a background thread and load the images into an ObservableCollection<>, bind that to the ListView and let the framework deal with the display.
I second what Greg D said, loading 200mb of images sounds like a recipe for problems.