WP7 GeoCoordinateWatcher in the background - c#

I'm wanted to wright a app which would alarm you when you are getting near a location.
I wanted to use the GeoCoordinateWatcher with PeriodicTask, but the test Task is invoked every 15min if i'm not mistaken. Can I somehow force the PeriodicTask to invoke more frequent? Or is there something else I can do to use the GeoCoordinateWatcher in the background which is not invasive for the UX. The app should work like for 2-3 hours and i like to update the location like every 5 minutes.

No, it's not possible for now. You only can run your application in foreground under lock screen to save battery life.

Register to the PositionChanged event of GeoCoordinateWatcher and set a low value of property MovementThreshold of GeoCoordinateWatcher to get the position changed events more frequently.
According to MSDN
This property specifies the minimum change in position that must take place
before the PositionChanged event is raised.

You could use a Timer to Start your Watcher every 5 minutes, just don't forget to Stop it too and so save the battery.

Related

Circular buffer for recording seconds before and after trigger using MediaCapture c#

I'm looking for an example of how to create a circular buffer using MediaCapture to record seconds before a trigger and after, something similar to Raspberry Pi's
picamera.PiCameraCircularIO(camera, seconds=clip_length).
I am creating a UWP app, which uses a USB camera and excepts a trigger, but I would like to have the Pre and Post timer around the trigger.
You need to implement a queue to store frames in it. Think you have one feame per second then you need queue of frames to store before and after triger specific seconds.
For example you need 15 seconds before and after the trigger.
In your queue you add image of each second to the queue and check when the queue got full (in this case 15 frames) dequeu one item and add new frame to queue. By this way you always have 15 frames before event got triggered. I think the next 15 frames after triggering event is simple enough ;)

Is there any default time interval for mediaended event to be fired?

I have a WPF application which dynamically loads video or image files(depending on user's choice, to a MediaElement control.
It is working fine when it is a video and gets the MediaEnded event fired on ending the video.
But when I load an image, the MediaEndedevent is fired within 5 seconds.
Is it a default value? or can I change it programmatically?
Is there any property to change this interval or disable such an option?
Is it possible to make it paused until a specific action?
I have set the following properties as follows
MediaControl1.LoadedBehavior = MediaState.Manual;
MediaControl1.UnloadedBehavior = MediaState.Manual;
MediaElement is a (very thin) wrapper around Windows Media Player (or rather - uses the same framework which is used by Windows Media Player). If you open an image in Windows Media Player - you will see it will "play" it like a slideshow (even for 1 image), for about 5 seconds. That's why you get MediaEnded event in 5 seconds - Windows Media Player plays slideshow with your image for that duration. I doubt there is a way to change this from WPF (because it's behavior of external program\framework, not related to MediaElement itself) and I'm not aware of the way to change this for Windows Media Player (and even if there is such a way - it will have global effect and you probably don't want to modify your clients computer in such a way).
To solve your problem - just don't use MediaElement for displaying images - use something like Image control. If you have really strong reasons to do that - you can pause MediaElement with Pause method after your "slideshow" has been loaded, then it will not fire MediaEnded event. All in all - I cannot imagine any use case where you really have to use MediaElement for images.
You can repeat the media when you load image. Handle MediaEnded event like this:
void me_MediaEnded(object sender, EventArgs e)
{
//play video again
mediaElement.Position = new TimeSpan(0, 0, 1);
mediaElement.Play();
}
Additionally see this. It may help:
https://stackoverflow.com/a/3406857/5675763

iOS video recording duration update UI

I'm using GPUImageVideoCamera and GPUImageMovieWriter to record a video. Everything is working good except I want to show the user a progress bar with the duration as the movie is being recorded. The GPUImageMovieWriter has a property called Duration, but I'm not sure how to make it update the UI in real time (as the video is being recorded).
I just need someone to point me in the right direction on how I can achieve this, I've been trying to figure this out for a few days now.
Set up a NSTimer to fire once every second or two and update the progress bar.

"Animating" a MapPolyLine in Silverlight

I need to animate a MapPolyLine such that on a given event, the start pin zips up to the end pin. The approach I am considerg is to animate frames such that I divide the MapPolyLine into n number of segments and decrease the TimeSpan ts between each frame along the logic of my chosing (to keep things simple, let's just say ts = ts / 2 after each cycle).
I know that one cannot animate the MapPolyLine, but one can change the appearance of the line by updating the latitude and longitude of the end position. My question concerns timing. My experience with multithreading is minimal, so I did not want to take the risk of a user running into a threading based error that may be difficult to diagnose. Should I:
use a simple DispatcherTimer and tick method
use a BackgroundWorker that reports progress every-time the TimeSpan has elapsed
use a dummy animation and attach an event handler to the rendering event
solution other than the above mentioned options?
Thank you in advance for your help!
Decided to use the DispatcherTimer considering the amount of time the animation is going to take - by creating a separate animation object that holds state and its own dispatch timer, it ended up being more efficient than using separate threads because the callback would mean interrupting the main UI thread and based on the requirements it was highly unlikely that there will be more than 2-3 of these animations occuring simultaneously with 95% or greater being only 1 animation at a time.

DispatcherTimer and UI refresh limits in C# silverlight

Again I apologize for a question that might be simple to all of you. I have a limited understanding of what goes behind the scenes in Silverlight.
I have a charting app (Visiblox) that I use as a rolling scope updated every 20ms, adding and removing a point. In pseudocode:
List<Point> datapoints= new List<Point>();
Series series = new Series(datapoints);
void timer_tick(){
datapoints.Add(new Point);
datapoints.RemoveAt(0);
// no need to refresh chart, it does refresh automatically
}
When running 6 series in this charting tool, it started to show a bit sluggish. Changing the tick to 10ms made no difference whatsoever, chart was updated at the same speed, so it seems that 20ms is the speed limit (UI or chart?).
I tried with CompositionTarget.Rendering and got the same results: below 20ms there was no difference in speed.
Then I accidentally enabled both and speed doubled. So I tested with multiple threads (2, 3, 4) and speed doubled, tripled and quadrupled. This has no locks yet, as I don't even know what process I need to generate a lock on, but got no data corruption nor memory leaks.
The question I have is why a sluggish chart at 20ms can not run at 10ms but is ridiculously fast when multithreaded? Is the UI refresh process being run faster? Is the chart computation doubled? Or is there a limit to how fast a single DispatcherTimer can be executed?
Thanks!
Edit: I have a background of embedded coding, so when I think of threads and timings, I immediately think of toggling a pin in hardware and hook up a scope to measure process lengths. I am new to threads in C# and there are no pins to hook up scopes. Is there a way to see thread timings graphically?
A DispatcherTimer, which fires its Tick event on the UI thread, is what's considered a low-resolution or low-accuracy timer because its Interval effectively means "tick no sooner than x since the last tick". If the UI thread is busy doing anything (processing input, refreshing the chart, etc.) then it will delay the timer's events. Furthermore, having a bunch of DispatcherTimer's ticking away on the UI thread at very low intervals will also slow down the responsiveness of your application because while the Tick event is being raised, the application can't respond to input.
So as you noted, in order to process data frequently, you should move to a background thread. But there are caveats. The fact that you aren't currently observing corruption or other bugs could be purely coincidental. If the list is being modified on a background thread at the same time the foreground thread is trying to read from it, you will eventually crash (if you're lucky) or see corrupt data.
In your example, you have a comment that says "no need to refresh chart, it does refresh automatically." This makes me wonder how does the chart know that you have changed the datapoints collection? List<T> does not raise events when it is modified. If you were using an ObservableCollection<T> I would point out that each time you remove/add a point you are potentially refreshing the chart, which could be slowing things down.
But if you are in fact using List<T> then there must be something else (perhaps another timer?) that is refreshing the chart. Maybe the chart control itself has a built-in auto-refresh mechanism?
In any event, the problem is a little bit tricky but not completely new. There are ways that you could maintain a collection on a background thread and bind to it from the UI thread. But the faster your UI refreshes, the more likely you'll be waiting for a background thread to release a lock.
One way to minimize this would be to use a LinkedList<T> instead of List<T>. Adding to the end of a LinkedList is O(1), so is removing an item. A List<T> needs to shift everything down by one when you remove an item from the beginning. By using LinkedList you can lock on it in the background thread(s) and you'll minimize the amount of time that you're holding the lock. On the UI thread you would also need to obtain the same lock and either copy the list out to an array or refresh the chart while the lock is held.
Another possible solution would be to buffer "chunks" of points on the background thread and post a batch of them to the UI thread with Dispatcher.BeginInvoke, where you could then safely update a collection.
The key here I think is to realise that Silverlight renders at a maximum frame rate of 60fps by default (customisable through your MaxFrameRate property). That means that the DispatcherTimer ticks will fire at most 60 times per second. Additionally, all the rendering work happens on the UI thread as well so the DispatcherTimer fires at the rate that the drawing is happening at best, as pointed out by the previous poster.
The result of what you're doing by adding three timers is just to fire the "add data" method 3 times per event loop rather than once, so it will look like your charts are going much faster but in fact the frame rate is roughly the same. You could get the same effect with a single DispatcherTimer and just add 3 times as much data on each Tick. You can verify this by hooking into the CompositionTarget.Rendering event and counting the frame rate there in parallel.
The ObservableCollection point made previously is a good one but in Visiblox there is a bit of magic to try and mitigate the effects of that so if you're adding data at a very fast rate the chart updates will be batched up at the rate of the render loop and unnecessary re-renders will be dropped.
Also regarding your point about being tied to the ObservableCollection implementation of IDataSeries, you are entirely free to implement the IDataSeries interface yourself, for example by backing it with a simple List. Just be aware that obviously if you do that the chart will no longer automatically update when data changes. You can force a chart update by calling Chart.Invalidate() or by changing a manually set axis range.

Categories