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.
Related
I'm looking to find a way to setup a variable inside a Parallel.Foreach loop and make the variable easily accessible anywhere in the system, to avoid having to pass all desired values deep into the system as parameters. This is primarily for logging purposes
Parallel.ForEach(orderIds, options, orderId =>
{
var currentOrderId = orderId;
});
And sometime later, deep in the code
public void DeepMethod(string searchVal)
{
// Access currentOrderId here somehow, so I can log this was called for the specified order
}
As noted in the comments, globally-scoped state for concurrently executing code is a poor design choice. If done correctly, you wind up with hard-to-maintain code and contention between concurrently executing code. If done incorrectly, you wind up with hard-to-find, hard-to-fix bugs.
There's not much context in your question, so it's impossible to suggest anything specific. But, given the description you've provided, the usual approach would be to define a class that represents the state for the concurrently executed operation, in which you keep the value or values that you want to be able to access at the "deep" level of the "system" (by this, I infer that you mean "deep" as in depth of call stack, and "system" as in the collection of methods involved in implementing this operation).
By using a class to contain the values and implementation of your concurrently executed operation, you then would have direct access to the value that's specific to that particular branch (thread) of the concurrently executed operation, as an instance field of your class, in the methods implemented in that class.
More broadly: a major tenet in writing concurrent code is to avoid sharing mutable data between threads. Shared data should be immutable (e.g. like a string object), and mutated data (like status values that you seem to be describing here) should be kept in data structures that are private to each thread.
So I'm working in a multithreaded environment and I wan't to use ImmutableArray all the time because it's thread safe.
Unfortunately, ImmutableArray implements thread unsafe interfaces and so Select method from LINQ returns IEnumerable.
This way, my thread safe variable becomes thread unsafe.
How do I map from ImmutableArray to ImmutableArray?
It seems that there are a lot of misunderstandings behind this question. You need to go look at the source code for the Select method and learn about the yield keyword.
Second, LINQ methods are made to be short-lived. You have various threads doing various processing tasks. Are you using a pipeline situation, where you want to transform data in one thread and pass the result to another thread? You have to be careful with the yield keyword in that situation; essentially, you need to flush (er, realize, for lack of a better word) your collections before passing them to the next thread so that the actual work is done in the present thread. In that scenario, object ownership kicks in and you don't need thread-safe collections.
In short, the enumerable returned from calling Select on ImmutableArray is perfectly thread-safe. You can realize it at any point and it won't give you any errors. Of course it will only iterate through the data that was contained in your collection at the time you called Select. It won't know anything about newly assigned instances.
So my title was fairly obscure, here is what I'm worried about. Can I invoke a method on an instance of a class that is declared outside of the block without suffering pitfalls i.e
Are there concurrency issues for code as structured below.
HeavyLifter hl = new HeavyLifter();
var someActionBlock = new ActionBlock<string>(n =>
{
int liftedStuff= hl.DoSomeHeavyLifting(n);
if (liftedStuff> 0)
.....
});
The source of my concerns are below.
The Block may have multiple threads running at the same time, and each of these threads may enter the DoSomeHeavyLifting method. Does each function invocation get its own frame pointer? Should I make sure I don't reference any variables outside of the CountWords scope?
Is there a better way to do this than to instantiate a HeavyLifter in my block?
Any help is greatly appreciated, I'm not too lost, but I know Concurrency is the King of latent errors and corner cases.
Assuming by frame pointer, that you mean stack frame, then yes, each invocation gets it's own stack frame, and associated variables. If parameters to the function are reference types, then all of the parameters will refer to the same object.
Whether or not it's safe to use the same HeavyLifter instance for all invocations depends on whether the DoSomeHeavyLifting method has side effects. That is, whether DoSomeHeavyLifting modifies any of the contents of the HeavyLifter object's state. (or any other referenced objects)
Ultimately whether it is safe to do this depends largely on what DoSomeHeavyLifting does internally. If it's carefully constructed in order to be reentrant then there are no problems calling it the way you have it. If however, DoSomeHeavyLifting modifies the state, or the state is modified as a side effect of any other operation, then the decision would have to be made in the context of the overall architecture how to handle it. For example, do you allow the state change, and enforce atomicity, or do you prevent any state change that affects the operation? Without knowing what the method is actually doing, it's impossible to give any specific advice.
In general when designing for concurrency it's usually best to assume the worst:
If a race condition can happen, it will.
When a race condition happens, you will lose the race in the most complex way your code allows.
Non-atomic state updates will corrupt each other, and leave your object in an undefined state.
If you use a lock there will be a case where you could deadlock.
Something that doesn't ever happen in debug, will always happen in release.
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.
I would like to have thread-safe read and write access to an auto-implemented property. I am missing this functionality from the C#/.NET framework, even in it's latest version.
At best, I would expect something like
[Threadsafe]
public int? MyProperty { get; set; }
I am aware that there are various code examples to achieve this, but I just wanted to be sure that this is still not possible using .NET framework methods only, before implementing something myself. Am I wrong?
EDIT: As some answers elaborate on atomicity, I want to state that I just want to have that, as far as I understand it: As long as (and not longer than) one thread is reading the value of the property, no other thread is allowed to change the value. So, multi-threading would not introduce invalid values. I chose the int? type because that is the on I am currently concerned about.
EDIT2: I have found the specific answer to the example with Nullable here, by Eric Lippert
Correct; there is no such device. Presumably you are trying to protect against reading the field while another thread has changed half of it (atomicity)? Note that many (small) primitives are inherently safe from this type of threading issue:
5.5 Atomicity of variable references
Reads and writes of the following data
types are atomic: bool, char, byte,
sbyte, short, ushort, uint, int,
float, and reference types. In
addition, reads and writes of enum
types with an underlying type in the
previous list are also atomic.
But in all honesty this is just the tip of the threading ice-berg; by itself it usually isn't enough to just have a thread-safe property; most times the scope of a synchronized block must be more than just one read/write.
There are also so many different ways of making something thread-safe, depending on the access profile;
lock ?
ReaderWriterLockSlim ?
reference-swapping to some class (essentially a Box<T>, so a Box<int?> in this case)
Interlocked (in all the guises)
volatile (in some scenarios; it isn't a magic wand...)
etc
(not to mention making it immutable (either through code, or by just choosing not to mutate it, which is often the simplest way of making it thread-safe)
I'm answering here to add to Marc's answer, where he says "there are also so many different ways of making something thread-safe, depending on the access profile".
I just want to add, that part of the reason for this, is that there are so many ways of not being thread-safe, that when we say something is thread-safe, we have to be clear on just what safety is provided.
With almost any mutable object, there will be ways to deal with it that are not thread-safe (note almost any, an exception is coming up). Consider a thread-safe queue that has the following (thread-safe) members; an enqueue operation, a dequeue operation and a count property. It's relatively easy to construct one of these either through locking internally on each member, or even with lock-free techniques.
However, say we used the object like so:
if(queue.Count != 0)
return queue.Dequeue();
The above code is not thread-safe, because there is no guarantee that after the (thread-safe) Count returning 1, another thread won't dequeue and hence cause the second operation to fail.
It is still a thread-safe object in many ways, particularly as even in this case of failure, the failing dequeue operation will not put the object into an invalid state.
To make an object as a whole thread-safe in the face of any given combination of operations we have to either make it logically immutable (it's possible to have internal mutability with thread-safe operations updating internal state as an optimisation - e.g. through memoisation or loading from a datasource as needed, but to the outside it must appear immutable) or to severely reduce the number of external operations possible (we could create a thread-safe queue that only had Enqueue and TryDequeue which is always thread-safe but that both reduces the operations possible, and also forces a failed dequeue to be redefined as not being a failure, and forces a change in logic on calling code from the version we had earlier).
Anything else is a partial guarantee. We get some partial guarantees for free (as Marc notes, acting on some automatic properties are already thread-safe in regards to being individually atomic - which in some cases is all the thread safety we need, but in other cases doesn't go anywhere near far enough).
Let's consider an attribute that adds this partial guarantee to those cases where we don't already get it. Just how much value is it to us? Well, in some cases it will be perfect, but in others it won't. Going back to our case of testing before dequeue, having such a guarantee on Count isn't much use - we had that guarantee and the code still failed in multi-threaded conditions in a way it wouldn't in single-threaded conditions.
What's more, adding this guarantee to the cases that don't already have it requires at least a degree of overhead. It may be premature optimisation to worry about overhead all the time, but adding overhead for no gain is premature pessimisation, so lets not do that! What's more, if we do provide the wider concurrency control to make a set of operations truly thread-safe, then we will have rendered the narrower concurrency controls irrelevant, and they become pure overhead - so we don't even get value out of our overhead in some cases; it's almost always purely waste.
It's also not clear how wide or narrow the concurrency concerns are. Do we need to lock (or similar) only on that property, or do we need to lock on all properties? Do we need to lock also on non-automatic operations, and is that even possible?
There is no good single answer here (they can be tricky questions to answer in rolling your own solution, never mind in trying to answer it in the code that would produce such code when someone else has used this [Threadsafe] attribute).
Also, any given approach will have a different set of conditions in which deadlock, livelock, and similar problems can occur, so we can actually reduce thread-safety by treating thread-safety as something we can just blindly apply to a property.
Without being able to find a single universal answer to those questions, there is no good way of providing a single universal implementation, and any such [Threadsafe] attribute would be of very limited value at best. Finally, at the psychological level of the programmer using it, it is very likely to lead to a false sense of security that they have created a thread-safe class when in fact they have not; which would make it actually worse than useless.
No, not possible. No free lunch here. The moment your autoproperties need even a tip more (thread safety, INotifyPropertyChanged) it is down to do yourself manually - no automatic properties magic.
According to the C# 4.0 spec this behavior is unchanged:
Section 10.7.3 Automatically implemented properties
When a property is specified as an automatically implemented property, a hidden backing field is automatically available for the property, and the accessors are implemented to read from and write to that backing field.
The following example:
public class Point {
public int X { get; set; } // automatically implemented
public int Y { get; set; } // automatically implemented
}
is equivalent to the following declaration:
public class Point {
private int x;
private int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}