Accessing value from WinRT component that is continously updated from managed code - c#

I am writing an application that will do some processing on the live preview images on windows phone 8. To achieve a good performance, I decided to use to the native interfaces provided with new sdk. Everythings work Ok for initializing the camera in native side, and feeding frames to a Image component in xaml. Now, I will write the code that will run in OnFrameAvailable method.
My problem is getting a processed value from the native component. Just to make things as simple as possible I just set an integer value in OnFrameAvailable and wrote an accessor of this value through a WinRT component to make it accesible in managed side.
I got stuck on what is an elegant way of accessing this value. When I try to access it in a loop in a thread i get the notorious "attempted to read or write protected memory " exception. I know the code does not make very much sense but I tried to minimize to point out the issue.
Here is how I do it:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
nativeCapture = new NativeCapture();
while (nativeCapture.Done == false) ;
viewFinderBrush.SetSource(nativeCapture.NPhotoCaptureDevice);
DrawElementThread = new Thread(drawElementsFunction);
DrawElementThread.Start();
base.OnNavigatedTo(e);
}
void drawElementsFunction()
{
while(true)
{
int a = nativeCapture.DetectedRectangleCoordinates; // Exception occurs here
}
}
Here you'll also notice that I am accsessing another value, Done, but I dont get the exception for it. However, I should note that is just set in the constructor of the native component whereas DetectedRectangleCoordinates is set everytime OnFrameAvailable called which I expect anytime a preview frame from the camera is available.
Therefore, I susptected that there might be some locking mechanism on WinRT components. Each time the OnFrameAvaible method called DetectedRectangleCoordinates becomes unaccessible. However, I could not find a statement about this and couldn't figure out how to debug such a thing.
I would really appreciate if you provide me with some pointers related to this or similar issues? Is it something related to access mechanisms in WinRT components? Or it is a bad threading practice I am doing? If so, how would I synchronize the thread in managed code and native code?
EDIT:
Putting a breakpoint on the line giving the exception and stepping does not cause the exception, and I get the expected value.
EDIT:
I put a breakpoint on the get function on native side. this pointer is pointing to null there. I could not understand why it is because it is being called from the object that is just constructed. ( nativeCapture object).

I have worked quite some time on what may be going wrong, but adding the code to Loaded event handler of the page solved the issue. I am not sure what it is related about, but when the code piece I have given in the question is run in OnNavigatedTo method, nativeCapture component might have self null pointer (this->) on its methods.
I hope this could help people if they have similar problems.

Related

Using COleDispatchDriver to dynamically load COM object leaking memory

I'm debugging some legacy code. It loads a user defined COM object, allows the user to call functions in it, and then releases it. However, we have found that every time we load and unload the COM object, we leak memory. As a test, we changed the code to load it and hang on to it, and keep re-using it until program exit and the leak went away.
Here are the relevant code snippets:
This C++ codeis is called to load the COM object, pszProgId is a string identifying the target DLL.
COleDispatchDriver *pDispatchDriver = NULL;
pDispatchDriver = new COleDispatchDriver();
if (!pDispatchDriver->CreateDispatch(pszProgId, &oleException))
{
throw &oleException;
}
pDispatchDriver->m_bAutoRelease = TRUE;
*ppvObject = (void *) pDispatchDriver;
void ** ppvObject is a pointer we pass around to generically hold different objects. It is part of a much larger structure.
And here is the code we call when releasing the COM object.
After we are done using the COM object, we release it as follows:
COleDispatchDriver* pDispatchDriver = (COleDispatchDriver*) (*((LONG_PTR*)(ppvObject)));
pDispatchDriver->ReleaseDispatch();
delete pDispatchDriver;
This is leaking about 1 meg every call. The target COM object is C#. Anyone have any idea what we're doing wrong or a better way to do what we're trying to do?
We are building this in VisualStudio 2015 in case that is relevant.
Re xMRi:
As already noted, we tried changing that flag to TRUE to no effect. As a sanity check, I tried doing that again after reading your post and again it did nothing to fix the memory leak. So for better clarity, I've updated my code to show it set to TRUE which is almost certainly the right value but still exhibiting the same memory leak described above.
ReleaseDispatch does nothing if you set m_bAutoRelease to FALSE. So in fact you don't free the instance of this COM object.
See the implementation:
void COleDispatchDriver::ReleaseDispatch()
{
if (m_lpDispatch != NULL)
{
if (m_bAutoRelease)
m_lpDispatch->Release();
m_lpDispatch = NULL;
}
}
So created the problem in setting m_bAutoRelease to FALSE yourself. Check the reasons why you are doing this.
You can directly get the LPDISPTACH pointer and call Release() but this is exactly what should be done when m_bAutoRelease is TRUE.

WPF DependencyObject calling thread exception

I have the following code which creates a temporary folder and uses a FileSystemWatcher to poll for files added to the folder on the Location property, and add them to a list: Scratchdisk.cs on Pastebin. The idea is to create a Scratchdisk object, and have FFmpeg extract video frames into it, the FileSystemWatcher builds a list of these files as FFmpeg creates them, and the list is presented as a DependencyObject that my UI binds to.
I'm binding to the Scratchdisk object like so:
<ItemsControl ItemsSource="{Binding Source=ThumbnailScratchdisk, Path=FileList}">
...
</ItemsControl>
On actually creating the object though, I get the following exception:
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
Additional information: The calling thread cannot access this object because a different thread owns it.
on line 28 get { return (List<string>)GetValue(FileListProperty); }
I think I need a Dispatcher.Invoke somewhere but I have no idea where, I don't know where the second thread is being created. I'm assuming it has something to do with the FileSystemWatcher writing to the file list.
Any help?
Thanks!
The way I access it is like this. It gets the UI Thread's Dispatcher
System.Windows.Application.Current.Dispatcher.Invoke(
(Action)(() =>
{
//Access the UI from here
}));
The main thing to note here between what I have and what you have listed in the comments is that mine will work regardless if you're in the behind code, the view model, a service class, wherever. Not all items have a Dispatcher on them so this.Dispatcher doesn't always work.
Even though this is a fairly old thread, I wanted to give a hint to anyone who ran into the same thing I did. This is an intentionally verbose description so the search engines can find it for the next guy/gal who hits this obscure behaviour.
After getting the SetValue/GetValue compile error described here, I needed to derive my VM from a DependencyObject.
I wanted to continue deriving my VM from our ViewModelBase, which was derived from our AbstractNotifyPropertyChanged class (can't derive from 2 full classes in C#, of course). Being the super smart guy I am, I figured I would add the DependencyObject derivation to my AbstractNotifyPropertyChanged class. I couldn't see any reason why this little change would have any detrimental effects. For many weeks, the application was running fine.
There is always a big hairy "however". During testing, it was discovered that one of my comboboxes crashed the entire application when an item was selected. This was due to an unhandled InvalidOperationException. "The calling thread cannot access this object because a different thread owns it." The only thing that made this combobox different was the fact that it used DependencyProperty for some values.
Four days of frustrating debugging led nowhere because none of my code was making the call. It was all coming from WPF, and blowing up when the call stack reached VerifyAccess in GetValue. Obviously when it is being called by the framework, attempting to call Invoke to cross threads was not going to happen? Where would you put the Invoke call?
Since normal debugging failed, I had to go about it the hard way. I retraced my checkin steps to find the last time the code worked. I already had the idea that it was somehow related to the DependencyProperty of the combobox, so seeing the code changes, my suspicions pointed to the DependencyObject derivation.
After some finagling of the code derivations to remove DependencyObject from the chain for all of my ViewModels (through ViewModelBase), and placing that derivation only in the exact locations that I needed it, The problem has been solved.
You can wrap your call inside an Action() being called from Dispatcher like this:
this.Dispatcher.BeginInvoke(new Action(() =>
{
// your code accessing UI elements here
}));

Undocumented .NET code related to Multi-Touch Manipulations throwing exception

A favorable outcome would be preventing this exception, preferably, or at least handling it gracefully.
I am getting an exception thrown within Microsoft code. On top of that, the method throwing the exception is System.Windows.Input.Manipulations.ManipulationSequence.ProcessManipulators, which I can't find in Microsoft Reference Source.
When the exception is thrown, I can see that one line down in the Call Stack window it references Windows.Input.Manipulations.ManipulationProcessor2D.ProcessManipulators, which does exist in Microsoft Reference Source.
But as you can see, it doesn't have a sibling class named ManipulationSequence.
As for the exception itself, it is a System.Argument.OutOfRangeException with a value of Timestamp values must not decrease. Parameter name: timestamp Actual value was 6590630705479.
The fully qualified signature of the method throwing the exception is System.Windows.Input.Manipulations.ManipulationSequence.ProcessManipulators(long timestamp, System.Collections.Generic.IEnumerable<System.Windows.Input.Manipulations.Manipulator2D> manipulators, System.Windows.Input.Manipulations.ManipulationSequence.ISettings settings)
It appears as if one other person in the universe has had this problem, but it could not be reproduced according to the only comment.
I have 6 MediaElement objects on a canvas that are all running videos when being manipulated, so I feel as though it might have something to do with the CPU being taxed and slowing down, possibly making timestamps be sent into the method out of order (though the same problem occurs when using Image rather than MediaElement). The exception happens sporadically, sometimes it will happen after just a few seconds of messing around with the objects, sometimes it can go for a few minutes or more of manipulating the objects.
My code that does the actual manipulation within ManipulationDelta looks like this:
//Get current values to manipulate
TransformGroup group = (TransformGroup)element.RenderTransform.Clone();
TranslateTransform translate = (TranslateTransform)group.Children[0].Clone();
ScaleTransform scale = (ScaleTransform)group.Children[1].Clone();
RotateTransform rotate = (RotateTransform)group.Children[2].Clone();
//...does manipulations on each by changing values...
//Apply transformation changes
group.Children[0] = translate;
group.Children[1] = scale;
group.Children[2] = rotate;
element.RenderTransform = group;
I have a Storyboard in XAML messing with the RotateTransform, so I can't really use MatrixTransform.
I am creating this using WPF with .NET 4.5.1. The error occurs in both Windows 8.1 and Windows 7. Any ideas on how to prevent this exception from occurring?
Some thoughts as I investigate the problem:
I also have ManipulationInertiaStarting in play here as a possible
cause of this error.
I just added e.Handled = true; to the end of ManipulationCompleted, which wasn't there before. I haven't got the error since (though, again, very sporadic, so it is hard to tell when it is fixed).
If a ManipulationDelta method is not yet complete, and it is hit again from user input, could there be some sort of race condition occurring where the first method hit is starved for CPU resources and the second runs through, then when the first method finally completes the timestamp created is in the past?
Per a comment, this isn't likely.
I conferred with a co-worker to gain better understanding. He helped me realize I can't swallow the exception from within my methods that handle manipulation events because the exception is happening before it gets there, in the actual creation of the manipulation data. So the only place I can handle the exception is on App.Main() (the first place in the Call Stack where my code exists), which makes handling it gracefully all the more difficult.
I had this exact problem myself.
After a lot of testing it could be reproduced with slower machines under heavy load.
The Application was for Digital Signage and showed a lot of different items ( Video, Html , Images , etc ) and had also some animations.
I am not sure about it but it seems to be a problem of handling the input events in time.
For myself i could "solve" this issue with outsourcing code from the manipulating to other code asynchronous and also profiling and rewriting code performance-wise.( shortened the path to run inside the event as much as possible and did everything needed to do also later with a Task )
Also i added an Exceptionhandler to my application to "ignore and log" this issue, because it had no other impact.
Feel free to contact me for more info on this.
PS: this is my first answer here, so i hope it is alright the way i wrote it
I had similar problems when developing for WinRT.
It's sometimes possible to use DispatcherUnhandledException event to ignore one particular exception. To do that, add event listener, check if exception is the one you want (because it's generally bad idea to suppress all exception), and then set Handled property.

Memory problem with application in C# Windows Forms

I have an application in C# which reserves too much memory when it wasn't supposed to. The executable is ~100Kb and the whole application is a couple thousands lines of code.
It's main component, has a timer which is responsible of creating events (instances of a class with a couple of attributes) and sending them to this http://timeline.codeplex.com/. The way the timeline accepts events, is by calling a ResetEvents function and passing a list of events. Because I have a timer, I put that inside the timer's code.
Running it like this, the application goes up to 300Mb of memory and I just end it to avoid crashing. If I remove the call of ResetEvents from the timer, then the application runs more smoothly consuming 60-70Mb. The application without the timeline, should run at 10-20Mb. There are no graphics or anything that could possibly use more than that. My guess is that something might be wrong with the timeline.
EDIT:
Here's a part of the code:
List<TimelineEvent> events = new List<TimelineEvent>();
...
inside timer
TimelineLibrary.TimelineEvent newevent = new TimelineLibrary.TimelineEvent();
...
newevent.StartDate = starttime;
newevent.EndDate = endtime;
newevent.Id = id;
newevent.Title = title;
newevent.Description = description;
newevent.Link = url;
newevent.EventColor = color;
events.Add(newevent);
timeline.ResetEvents(events);
...
This code is inside the timer. I just create a TimelineEvent, add it to a list and call ResetEvents. Removing that last line, doesn't cause the memory problem.
Since it is very hard to see what your problem is without more code, I suggest trying some kind of memory profiler to locate where and when the memory gets allocated.
Try for example RedGates Memory Profiler, they have a time-based trial.
Follow this walk-through to get up to speed and learn a bit what to look for and how.
For more options regarding .NET memory profilers, see this thread.
Good luck!
What is the type of the events variable you passed to ResetEvents?
Without seeing the code, the only suspicious behavior I can in what you did post, is that perhaps the ResetEvents method does not really clear the collection it receives, but instead does something on the state of the timeline variable.
Using a memory profiler is a great idea. If you expect people here to help you find a memory leak otherwise, please post more of your code. Ideally, you could reproduce the problem with minimal code and then post that.

When does a param that is passed by reference get updated?

Suppose I have a method like this:
public void MyCoolMethod(ref bool scannerEnabled)
{
try
{
CallDangerousMethod();
}
catch (FormatException exp)
{
try
{
//Disable scanner before validation.
scannerEnabled = false;
if (exp.Message == "FormatException")
{
MessageBox.Show(exp.Message);
}
}
finally
{
//Enable scanner after validation.
scannerEnabled = true;
}
}
And it is used like this:
MyCoolMethod(ref MyScannerEnabledVar);
The scanner can fire at any time on a separate thread. The idea is to not let it if we are handling an exception.
The question I have is, does the call to MyCoolMethod update MyScannerEnabledVar when scannerEnabled is set or does it update it when the method exits?
Note: I did not write this code, I am just trying to refactor it safely.
You can think of a ref as making an alias to a variable. It's not that the variable you pass is "passed by reference", it's that the parameter and the argument are the same variable, just with two different names. So updating one immediately updates the other, because there aren't actually two things here in the first place.
As SLaks notes, there are situations in VB that use copy-in-copy-out semantics. There are also, if I recall correctly, rare and obscure situations in which expression trees may be compiled into code that does copy-in-copy-out, but I do not recall the details.
If this code is intended to update the variable for reading on another thread, the fact that the variable is "immediately" updated is misleading. Remember, on multiple threads, reads and writes can be observed to move forwards and backwards in time with respect to each other if the reads and writes are not volatile. If the intention is to use the variable as a cross-thread communications mechanism them use an object actually designed for that purpose which is safe for that purpose. Use some sort of wait handle or mutex or whatever.
It gets updated live, as it is assigned inside the method.
When you pass a parameter by reference, the runtime passes (an equivalent to) a pointer to the field or variable that you referenced. When the method assigns to the parameter, it assigns directly to whatever the reference is pointing to.
Note, by the way, that this is not always true in VB.
Yes, it will be set when the variable is set within the method. Perhaps it would be best to return true or false whether the scanner is enabled rather than pass it in as a ref arg
The situation calls for more than a simple refactor. The code you posted will be subject to race conditions. The easy solution is to lock the unsafe method, thereby forcing threads to hop in line. The way it is, there's bound to be some bug(s) in the application due to this code, but its impossible to say what exactly they are without knowing a lot more about your requirements and implementation. I recommend you proceed with caution, a mutex/lock is an easy fix, but may have a great impact on performance. If this is a concern for you, then you all should review a better thread safe solution.

Categories