WPF DependencyObject calling thread exception - c#

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
}));

Related

Can I use Invoke instead of BeginInvoke to address suspension of Dispatcher processing?

One of our clients has reported an issue with one of our Add-ins becoming unresponsive. The error reported contains a stack trace that goes deep into the bowels of WPF and I won't distract you with that. Suffice to say that the top level error reads:
Dispatcher processing has been suspended, but messages are still being processed.
The same code works perfectly on my, and as far as I know any other, machine. All the code does is instantiate a WPF window and call its .ShowDialog() method.
Looking through issues with the same error, I find answers such as this:
Dispatcher throws InvalidOperationException on Messagebox.Show in Textchanged event
or
WPF : Dispatcher processing has been suspended, but messages are still being processed
In both cases the answer provided is to use Dispatcher.BeginInvoke
The problem with that is that this call is asynchronous and I need to wait for user response. So I use Dispatcher.Invoke instead:
Dispatcher.Invoke(Sub() oAIC.ShowDialog(), System.Windows.Threading.DispatcherPriority.Normal)
Once again this works perfectly on my machine but that means nothing. The original code worked perfectly on my machine, too.
So my question is:
Is this even worth pursuing? Or is the fact that I use .Invoke instead of .BeginInvoke equivalent to me just using the original .ShowDialog() directly so I'm wasting my time?
Suffice to say that the client in question is not of the cooperative kind. Other clients would be happy for me to give them a trial version and report back, but this person simply wants a solution and doesn't want to be bothered with anything else. As this has never been reported by any other client I can't even find another "guinea pig" to try this on, so all I have left is the option to ask it here in the hope that someone with sufficient expertise can tell me "yes this is a good way forward" or "you're wasting your time". Sorry if this doesn't quite fit the model for asking questions here but I'm at the end of my rope...
further clarification after seeing Peregrine's answer
The code is part of an Office Add-in (in this case for Microsoft Word). The WPF dialog I'm trying to display pops up several levels down from a button click in the Ribbon Bar.
I put the code behind the button click into a function
DoTheButtonCode()
and called it as follows
Await System.Threading.Tasks.Task.Run(AddressOf DoTheButtonCode)
When I tried this, an error was raised:
An exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll but was not handled in user code
Additional information: The calling thread must be STA, because many UI components require this.
Now this is the weird thing. In the original Button Click event, the apartmentstate of system.threading.thread.currentthread is STA but when I then step into the DoTheButtonCode and I check system.threading.thread.currentthread its apartmentstate is MTA
further clarification
Ok - tried something else:
Changed DoTheButtonCode to an Async Function:
Private Async Function DoTheButtonCode() As Threading.Tasks.Task(Of Integer)
The button Click event handler method is now defined Private Async Sub, and within it I call
Await DoTheButtonCode()
This actually works, apart from this niggling warning that appears in the function definition of DoTheButtonCode: "this async method lacks 'Await' operators and so will run synchronously" (etc)
So while this does work I suspect that I'm kidding myself here.
I think I'm about ready to give up. I'll just add a try/catch construct around my original ShowDialog call and if the error is raised at least it will simply do nothing rather than crash :(
Thanks for all your help, Peregrine
I'm doing something very similar in my library for displaying message dialogs in a MVVM pure manner.
The only differences I can see between my code and yours is
I'm using Dispatcher.InvokeAsync() rather than Dispatcher.Invoke() - which makes the call awaitable.
I'm creating my dialog window inside the Dispatcher.BeginInvoke() call - it's not clear where your oAIC window is being created.
private async Task<perDialogButton> _ShowDialogAsync(object viewModel, object content, string title, perDialogButton buttons, perDialogIcon dialogIcon)
{
// get control associated with ViewModel instance
var associatedControl = ...
return await associatedControl.Dispatcher.InvokeAsync(() =>
{
var window = new perDialog
{
// set dialog properties
...
};
window.ShowDialog();
return window.SelectedButton;
});
}
Mode details, and the full source code on my blog post

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.

Accessing value from WinRT component that is continously updated from managed code

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.

Lazy<T>: "The function evaluation requires all threads to run"

I have a static class with some static properties. I initialized all of them in a static constructor, but then realized that it is wasteful and I should lazy-load each property when needed. So I switched to using the System.Lazy<T> type to do all the dirty work, and told it to not to use any of its thread safety features since in my case execution was always single threaded.
I ended up with the following class:
public static class Queues
{
private static readonly Lazy<Queue> g_Parser = new Lazy<Queue>(() => new Queue(Config.ParserQueueName), false);
private static readonly Lazy<Queue> g_Distributor = new Lazy<Queue>(() => new Queue(Config.DistributorQueueName), false);
private static readonly Lazy<Queue> g_ConsumerAdapter = new Lazy<Queue>(() => new Queue(Config.ConsumerAdaptorQueueName), false);
public static Queue Parser { get { return g_Parser.Value; } }
public static Queue Distributor { get { return g_Distributor.Value; } }
public static Queue ConsumerAdapter { get { return g_ConsumerAdapter.Value; } }
}
When debugging, I noticed a message I've never seen:
The function evaluation requires all threads to run
Before using Lazy<T>, the values were displayed directly. Now, I need to click on the round button with the threads icon to evaluate the lazy value. This happens only on my properties that are retrieving the .Value of Lazy<T>. When expanding the debugger visualizer node of the actual Lazy<T> object, the Value property simply displays null, without any message.
What does that message mean and why is it displayed in my case?
I've found an MSDN page titled "How to: Refresh Watch Values" explaining it:
When you evaluate an expression in the debugger, one of two refresh icons might appear in the Value column. One refresh icon is a circle that contains two arrows, which circle in opposite directions. The other is a circle that contains two wavy lines that resemble threads.
...
If the two threads appear, the expression was not evaluated because of a potential cross-thread dependency. A cross-thread dependency means that evaluating the code requires other threads in your application to run temporarily. When you are in break mode, all threads in your application are typically stopped. Allowing other threads to run temporarily can have unexpected effects on the state of your program and causes the debugger to ignore events such as breakpoints.
I'd still like a better explanation if anyone can give it. Questions that this doesn't answer include: What kind of evaluation requires all threads to run? How does the debugger identify such a case? What exactly happens when you click the thread refresh icon?
EDIT: I think I've stumbled across the answer when examining Lazy<T> under ILSpy (for a completely different reason). The getter of the Value property has a call to a Debugger.NotifyOfCrossThreadDependency(). MSDN has this to say:
[...] performing a function evaluation typically requires freezing all threads except for the thread that is performing the evaluation. If the function evaluation requires execution on more than one thread, as might occur in remoting scenarios, the evaluation will block. The NotifyOfCrossThreadDependency notification informs the debugger that it has to release a thread or abort the function evaluation.
So basically, to prevent the annoying case where you try to evaluate some expression and Visual Studio just hangs for 30 seconds and then informs you that "a function evaluation has timed out", the code has a chance to inform the debugger that it must unfreeze other threads for the evaluation to succeed or otherwise the evaluation will block forever.
Since running other threads may disrupt your debugging session, as usually when you evaluate an expression all other threads are kept frozen, the debugger doesn't automatically proceeed and warns you before letting you jump down the rabbit hole.
My guess would be that the debugger is trying to avoid influencing the application state by loading the properties for you.
You have to remember, that lazy load only happens when you reference/access the properties.
Now, in general, you do not want debugging to affect the state of the application, otherwise that will not give an accurate representation of what the application state should be (Think multi threaded apllications and debugging)
Have a look at Heisenbug
I struggled with this for hours and found the original error message about requiring all threads to run misleading. I was accessing an existing database from a new solution and creating new Entity Framework entity POCOs and data access layers within the new solution to access and map to the DB.
I did two things initially wrong. I didn't properly define the primary key in my C# entity POCO, and the table I was accessing had a unique schema in the DB (it was not dbo.tablename but edi.tablename).
In my DbContext.cs file, I did the following to map the table under the right schema. Once I corrected these things the error went away and it worked just fine.
protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
{
base.OnModelCreating(dbModelBuilder);
dbModelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
dbModelBuilder.Entity<TableName>().ToTable("TableName", schemaName: "EDI");
}
Create a local variable and assign it the value you want to inspect.
This will let you inspect it because the debugger doesn't have to worry about whether or not accessing the property will disturb your application, because it will have already accessed it when assigning it to the local variable.
For me, I found it didn't matter if I had this.Configuration.LazyLoadingEnabled = false; or = true;, if I had the line in my DBContext or not. It seems to occur, from my reading up on the problem, because a thread is occurring & the debugger wants permission to run it/is warning you before it spurs it. Apparently, in some cases, you can even allow it to proceed according to MUG4N's answer here: Visual Studio during Debugging: The function evaluation requires all threads to run
But what I found was I could get around the issue.
2 options:
Add .ToList() on your Queues:
var q = db.Queues.OrderBy(e => e.Distributor).ToList();
I found a workaround by selecting Non-Public Members > _internalQuery > ObjectQuery > Results View.

Control.Refresh() Across Threads

OK, please disregard what has gone before. I'm not getting the errors anymore, so it seems my problem is with getting a Chart to update when I change the values to which the Chart is data bound.
//Disregard below here
Hi all. I have a WinForms application that has a panel, panel1. A background thread creates some other controls that then get added to panel1 like so
panel1.Controls.AddRange(myArrayOfControls);
This works great and I can see my controls get added. But, when new data comes in on another thread, I update values in the controls' parent objects and then need to Refresh() to get the display to update with the new values. Calling Refresh() in either context, the thread where the data comes in or the objects that receive the updated data causes an InvalidOperation exception because Invoke is required. I've tried using Invoke in my model objects and also the thread where the data is incoming and can't seem to shake the error.
If anyone has some guidance I'd greatly appreciate it.
UPDATE: Here's a little more info. I didn't think it would require it, but I was wrong. :)
I have an object class MyObject. This MyObject class gets created in a thread called topologyThread. Data comes in on dataThread. Instances of MyObject have a Panel instance variable and the Panel has child Controls including two Charts from the System.Windows.Forms.DataVisualization.Charting namespace. So, as data comes in on dataThread, I update the respective data values in the MyObject objects and then need to refresh the Charts to show the updated data.
I do know the data is processing fine. In my MyObject class, I'm logging the new values to Console in the setter for the property and see the new values show up.
You must do both operations (refresh and updating of control's parent object) from the main UI thread. If you are modifying a control from a background thread and not getting an exception that is bad luck because it is definitely an error.
The best way to do this is to use
theControl.Invoke(new MethodInvoker(MyUpdateMethod));
If you have a sample of how the update is done, we can give a better sample on how to properly call it from the background thread.
JaredPar is a pretty good answer. I would like to add to it a bit as to the reason your code sort of works.
With windows forms you can talk to the UI thread from other threads. This is really bad practice in all cases.
The catch is that when you do it, it is hard to catch because sometimes the UI will work as if nothing is wrong. item will get added or changed and the UI will reflect the changes. However other times running the same exact code, it will not work.
That is the catch with touching the UI from any thread other then the UI thread. The out come is inconsistent and that is why is very bad practice.
God I wish I could comment. :)
JaredPar's answer is good. It can cause problems in some instances (notably when the method is invoked before the form is finished being constructed). Here's a somewhat more robust implementation (using extension methods)
public static class ControlInvokeExtensions
{
public static void InvokeOnHostThread(Control host, MethodInvoker method)
{
if (IsHandleCreated)
Invoke(new EventHandler(delegate { method(); }));
else
method();
}
}
now you can call it this way
panel1.InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls));
or if you're in the form:
InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls));

Categories