Do I only need to use Invoke, if the access is a write access? Is it safe to get the property of a GUI object without invoke?
new Thread(() =>
{
Invoke((MethodInvoker)(() => mbrVerticalProgressBar1.Value++));
if (TaskbarManager.IsPlatformSupported)
{
TaskbarManager.Instance.SetProgressValue(
mbrVerticalProgressBar1.Value,
mbrListOfURLsCount);
}
}).Start();
The MSDN Library makes no bones about it, it declares every method and property of the Control class thread-unsafe except InvokeRequired, BeginInvoke, Invoke and CreateGraphics.
That's not entirely accurate, there certainly are a few properties that are accidentally thread-safe because they use a backing variable. You'd have to know the actual implementation of the property getter and take a gamble on it not going to chance in the future.
And yes, ProgressBar.Value uses such a backing variable, the private value field. You can tell from the Reference Source or a decompiler. However, that's only for the getter, the setter is most certainly not. Because it needs to actually get the visible appearance of the control to change.
Btw, always favor BeginInvoke over Invoke. Invoke has pretty unpleasant characteristics, it is very apt to cause deadlock and it is very slow. You only need Invoke() when you need its return value, not the case here.
It depends upon what that write is going to do. For example you can read/write Tag property of control in any thread without any problem.
Technically anything that fires a call to Control.Handle property should be in UIThread because UIThread owns that control, so it should be accessed in that thread only, else it will end up throwing an InvalidOperationException when debugger attached.
Related
A common exception one can get when working with multiple threads in WPF is:
The calling thread cannot access this object because a different thread owns it
What are the options to deal with this properly?
Depending on the situation there are various options:
Accessing a control from another thread
e.g. updating a TextBlock with progress information.
Data Binding:
In this case the easiest thing you can do is avoiding the direct interaction with the control. You can just bind the property you want to access or modify to an object whose class implements INotifyPropertyChanged and then set the property on that object instead. The framework will handle the rest for you. (In general you rarely should need to interact with UI-elements directly, you can almost always bind the respective properties and work with the binding source instead; one case where direct control access may be necessary is control authoring.)
There are some cases where data binding alone is not enough, for example when trying to modify a bound ObservableCollection<T>, for this you need...
Dispatching:
You can dispatch your accessing code to the thread owning the object, this can be done by calling Invoke or BeginInvoke on the Dispatcher owning the object being accessed (getting this Dispatcher is possible on another thread).
e.g.
new Thread(ThisThreadStart).Start();
void ThisThreadStart()
{
textBlock.Dispatcher.Invoke(new Action(() => textBlock.Text = "Test"));
}
If it is not clear on which thread a method is executed you can use Dispatcher.CheckAccess to either dispatch or execute an action directly.
e.g.
void Update()
{
Action action = () => myTextBlock.Text = "Test";
var dispatcher = myTextBlock.Dispatcher;
if (dispatcher.CheckAccess())
action();
else
dispatcher.Invoke(action);
}
If an object is not a DispatcherObject and you still need the associated Dispatcher you can use Dispatcher.CurrentDispatcher in the thread creating the object (so doing this in the method being executed by a thread will not do you any good). For convenience as you usually create objects on the application's main UI thread; you can get that thread's Dispatcher from anywhere using Application.Current.Dispatcher.
Special cases:
BackgroundWorker
Move any control access to ProgressChanged as it occurs on the thread that created the instance (which should of course be the UI-thread)
Timers
In WPF you can use the DispatcherTimer for convenience, it does the dispatching for you so any code in Tick is invoked on the associated dispatcher. If you can delegate the dispatching to the data binding system you of course can use a normal timer as well.
You can read more about how the Dispatcher queue works and WPF threading in general on MSDN.
Accessing an object created on another thread
e.g. loading an image in the background.
If the object in question is not Freezable you should in general simply avoid creating it on another thread or restricting access to the creating thread. If it is Freezable you just need to call Freeze to make it accessible to other threads.
Accessing a data object from another thread
That is, the type whose instance is being updated is user-code. If an exception is thrown this situation probably came about by someone using DependencyObject as base type for a data class.
This situation is the same as accessing a control and the same approaches can be applied but usually it should be avoided in the first place. Granted, this allows for simple property change notifications via dependency properties and those properties can also be bound but often enough this is just not worth giving up thread-independency. You can get change notifications from INotifyPropertyChanged and the binding system in WPF is inherently asymmetrical, there always is a property that is bound (target) and something that is the source for this binding. Usually the UI is the target and the data is the source, meaning that only UI components should need dependency properties.
That would be several hundred lines of code, for something I "figured out".
But the summary is:
App_OnStartup
generate a background thread
in the callback,
Call
Application.Current.MainWindow.Dispatcher.CheckAccess() - gets the exception
Application.Current.Dispatcher.CheckAccess() does not
I have a udp listener object that communicates through events where the method/callbacks are +='ed in my mainWindow wpf .cs file.
The event handler functions are called with parameters, one being the message I want displayed in a listbox in the mainWindow.cs
Using the information in this thread by H.B. above;
I have added, tested and handled the crossthread in wpf in my eventhandler callback using the following code, but I use a real message not a hard coded one:
listBox1.Dispatcher.Invoke(new Action(() => listBox1.Items.Add("MessageHere")));
UPDATE:
This is better because you can put more things in the anonymous function.
listBox1.Dispatcher.Invoke((Action)delegate
{
listBox1.Items.Add(e.ReaderMessage);
});
Refer the thread-safe call tutorial at MSDN, have a look at following statments:
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired) {
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
} else {
this.textBox1.Text = text;
}
Of course, I've used it many times in my codes, and understand a little why to use it.
But I still have some unclear questions about those statements, so anybody help me to find them out, please.
The questions are:
Will the code can run correctly with the statements in the if body only? I tried and seems it just cause the problem if the control is not initialize completely. I don't know is there more problem?
Which the advantage of calling method directly (else body) instance via invoker? Does it save resource (CPU, RAM) or something?
Thanks!
You can of course always call using the Invoker, but:
It usually makes the code more verbose and difficult to read.
It is less efficient as there are several extra layers to contend with (setting up delegates, calling the dispatcher and so on).
If you are sure you'll always be on the GUI thread, you can just ignore the above checks and call directly.
If you always run just the first part of the if statement, it will always be fine, as Invoke already checks if you're on the UI thread.
The reason you don't want to do this is that Invoke has to do a a lot of work to run your method, even if you're already on the right thread. Here's what it has to do (extracted from the source of Control.cs):
Find the marshaling control via an upward traversal of the parent control chain
Check if the control is an ActiveX control and, if so, demand unmanaged code permissions
Work out if the call needs to be invoked asynchronously to avoid potential deadlock
Take a copy of the calling thread's execution context so the same security permissions will be used when the delegate is finally called
Enqueue the method call, then post a message to invoke the method, then wait (if synchronous) until it completes
None of the steps in the second branch are required during a direct call from the UI thread, as all the preconditions are already guaranteed, so it's definitely going to be faster, although to be fair, unless you're updating controls very frequently, you're very unlikely to notice any difference.
In CLR via CSharp chapter 10 "Properties" Jeff Richter writes:
A property method can take a long time to execute; field access always
completes immediately. A common reason to use properties is to
perform thread synchroni- zation, which can stop the thread forever,
and therefore, a property should not be used if thread
synchronization is required. In that situation, a method is preferred.
Also, if your class can be accessed remotely (for example, your class
is derived from System.MarshalByRefObject), calling the property
method will be very slow, and therefore, a method is preferred to a
property. In my opinion, classes derived from MarshalByRefObject
should never use properties.
Is this the case even if the property is defined to just return the private field? Why is a Method preferred in synchronization? and why is a Method preferred in MarshalByRefObject scenario?
To clarify my question: Jeff seems to be making a blanket statement that Properties are not advisable, and that methods are preferable in those 2 scenarios. as Joe White pointed out, properties can have arbitrary code. But methods can run the same arbitrary code. That's the part i'm having difficulty with. Is there actually advantage in using methods over properties (given the same code is used) for synchronization or marshaling, or does he merely have a problem with language convention?
I think he's making the point that, because a property can run any arbitrary code, the calling code shouldn't assume that it will finish immediately.
If all the property does is return a field, then its method body will actually be inlined by the JIT compiler and it'll be just as fast as a field access. So it's not that properties are somehow slower; it's that they're black boxes. If you don't know how a property is implemented, you can't make assumptions about it returning quickly.
(That said, making a slow property would be a clear violation of the .NET Framework Design Guidelines, specifically this one: "Do use a method, rather than a property, [if the] operation is orders of magnitude slower than a field set would be".)
As for his suggestion of using methods instead, I can't make any sense of that. Properties are methods: the property getter is a method (typically named get_PropertyName), and the property setter is a method (set_PropertyName), and code that reads the property is compiled to code that makes a method call to get_PropertyName. There's nothing special that would make a property any slower than a method.
I think the point is that property access looks like a field access, so people don't expect anything unusual.
If you have a property that can take a long time, you should rewrite it into a method. It won't make your code perform any better, but it will be more clear that it might take a long time.
As far as performance goes, there is no difference between property access and method call. Actually property access is just a method call.
A Method is not faster than a property, but a method is not expected to be as fast as a property. So the method is preferred to make clear that it might take some time (because of thread synchronization in this case).
Fields are not "executed" at all. Accessing a field is directly accessing memory.
I'm jusing Jurassic javascript compiler to run javascript in my C# application. Now, jurassic isn't thread-safe, and I call functions (in javascript) from threads all over the place, which I figured wasn't that smart. What I could do was ofcause just to create a simple lock on the javscript-engine, however, what I want is a programming model similar to the one you have when working with a GUI thread in WPF or WinForms. So, I spawned a thread, and created my javascript-engine inside that thread, and what I would like is that no other threads are allowed to edit the objects created in that thread (which will just be the javascript-engine and all the js-objectes). And then, to call js-code from other thread I'd like to use a dispatcher, or something similar, to make the js-thread run the code.
Is this possible in C#?
It doesn't quite answer your question but you may want to take a look at this MSDN article. It talks about the approach that WPF took with their objects and the Dispatcher model, as well as the Dispatcher, DispatcherObject and DispatcherSynchronizationContext classes.
What they recommend for individual objects is to inherit from DispatcherObject (which may not be feasible for your situation) and call the inherited VerifyAccess() method on public access.
public class ThreadOwnedObject : DispatcherObject
{
private string field;
public string ExposedProperty
{
get { return field; }
set
{
VerifyAccess();
field = value;
}
}
}
And the invocation would use the inbuilt Dispatcher.
ThreadOwnedObject ownedInstance = new ThreadOwnedObject();
ownedInstance.Dispatcher.Invoke(new Action(() => ownedInstance.ExposedProperty = "foo"));
Alternately, if that or the DispatcherSynchronizationContext in the article doesn't fit your needs, I imagine that you could probably create a mechanism that mimics the DispatcherObject by holding onto the Thread.CurrentThread.ManagedThreadId when an object is created and perform checks against that value for every exposed access. Beyond that or an equivalent, I don't think that there's a built-in mechanism that will associate a random object with a given thread.
I'm not quite sure what you are asking, but I'll try to help anyway.
Can you use a semaphore to lock the thread running the javascript engine? Even if you don't use the Semaphore class, you could use a boolean or "lock" keyword to protect the code block with the executing engine. The objects produced by that thread could be hidden by the class with the engine until you are ready. You could also expose a method in that class that would allow code injection or object fetching from behind the protected code.
(There's a tiny bit of history to this question, please bear with me)
In this question, I talked about the possibility of centralising the 'cross thread' hocus-pocus that is required for updating the GUI like so:
//Utility to avoid boiler-plate InvokeRequired code
//Usage: SafeInvoker.Invoke(myCtrl, () => myCtrl.Enabled = false);
public static void Invoke(Control ctrl, Action cmd)
{
if (ctrl.InvokeRequired)
ctrl.BeginInvoke(new MethodInvoker(cmd));
else
cmd();
}
Last week, mulling over the fact that this always happens (in my code) when handling an event, and partly inspired by Dustin Campbell's event extension method, I cooked up this:
//Utility to avoid boiler-plate SafeInvoker.Invoke code
//Usage obj.EventRaised += obj_EventRaised.OnGUIThread(controlreference);
public static EventHandler OnGUIThread(this EventHandler h, Control ctrl)
{
// lambda expressions are not syntactic sugar, they are syntactic crack!
return (s, e) => SafeInvoker.Invoke(ctrl, () => h(s, e));
}
The thing that bugs me here is always having to have a control to hand. As far as I know, there is only one GUI thread, so any control would do here.
I got to wondering about creating a 'GUIContext' singleton and throwing it a reference to my main form when the application starts up, then accessing that from my extension method, thus removing the need for the ctrl parameter.
Is this a bad idea, and if so, why? Is there a better way to do it? I know that in Rx there is a notion of Context, but I'm not aware of anything equivalent in vanilla WinForms. I can imagine there might be a problem if I try to update a control that is not yet handled (but in that case I'm screwed anyway).
Doing this would restrict you to a single main form and a single GUI thread. But the need for a main GUI thread is as much a requirement of .NET forms (and the underlying Win32 API) as anything, so it's not very likely to change.
You would know if having A single main form for your app is likely to change or not. Even if it it did, your singleton would be a better place to keep track of which form was "main" than to pass that around to all of the background threads.
On the whole, this looks like a reasonable design to me. I've used a global variable to hold hwndMain in my unmanaged apps for more than a decade and never regretted it.
I suspect that in many cases the SynchronizationContext.Current may do much of what you want here (watch out - it can also be null). But just Send or Post to that.
If you do keep a global object - perhaps type it just as ISynchronizeInvoke - less chance of unintended abuse.