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

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.

Related

Is there an issue with making a custom polling method for Selenium automation?

First of all, here's the C# code (even though the question is language-independent):
public static void PollClick(IWebElement element, int timeout = defaultTimeout, int pollingInterval = defaultPollingInterval)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.Elapsed < TimeSpan.FromSeconds(timeout))
{
try
{
element.Click();
break;
}
catch (Exception)
{
System.Threading.Thread.Sleep(pollingInterval);
}
}
}
This one is for clicking an element, but I could easily replace the click command with something else (visibility check, send text, etc). I'm setting up automation for IE, Edge, Firefox, and Chrome. I've come across a few situations where a certain web driver has a bug or the web page misbehaves for a browser (an element remains obscured, a crash with no stack trace, and other strange issues). This method has been used sparingly (once or twice) as I already have made use of the existing waits available for Selenium and have even created wrapper functions around those waits (including one that waits until an exception is no longer being thrown). Is it a bad idea to have this method handy? It did pass code review but I'm just curious as to what else I could do for anomalous situations.
There’s nothing wrong with executing such a strategy. In point of fact, the language bindings themselves do exactly that in the WebDriverWait construct. In C# (and other language bindings too, I believe) there is a generic version that is not specific to waiting on elements called DefaultWait which gives the user more control over things like what exceptions are caught and ignored, what timing interval to use, and so on. The caveat to repeating actions on the page like clicking elements is that there is a chance for the action to happen more than once, which may have unexpected side effects.
Apparently there is no issue at all in implementing a custom polling method as per your code.
But the question is Why?
The Selenium Language Bindings Java, Python, C#, Ruby internally implements the same and provides us the APIs to achieve the same. So adding one more layer to the existing layers will definitely will have an impact on the performance of your Script Execution.
Nevertheless, in general as per this discussion when you creating a new function the usual costs of making the function call are :
Push the variables onto the stack memory.
Push the return address onto the stack memory.
Branch-out to the destination function.
Creating a new stack frame in the destination function.
Now, at the end of the function the undoing of all the above :
Destroy the local objects created.
Pop the return address.
Destroy the pass-by-value parameters.
Reset the stack pointer to where it was before the parameters were pushed to stack memory.
So, creating and calling an extra function stands pretty costly in terms of System Resources. To avoid that we can easily avail the services exposed by the APIs particularly the ExpectedConditions Class as follows :
Presence of elements : An expectation for checking that all elements present on the web page that match the locator.
Visibility of elements : An expectation for checking that all elements present on the web page that match the locator are visible. Visibility means that the elements are not only displayed but also have a height and width that is greater than 0.
Click/Interactibility of element : An expectation for checking an element is visible and enabled such that you can click it.

Are Private properties of a class called within a Parallel.Foreach body Thread Safe?

I am tasked with writing a system to process result files created by a different process(which I have no control over) and and trying to modify my code to make use of Parallel.Foreach. The code works fine when just calling a foreach but I have some concerns about thread safety when using the parallel version. The base question I need answered here is "Is the way I am doing this going to guarantee thread safety?" or is this going to cause everything to go sideways on me.
I have tried to make sure all calls are to instances and have removed every static anything except the initial static void Main. It is my current understanding that this will do alot towards assuring thread safety.
I have basically the following, edited for brevity
static void Main(string[] args)
{
MyProcess process = new MyProcess();
process.DoThings();
}
And then in the actual process to do stuff I have
public class MyProcess
{
public void DoThings()
{
//Get some list of things
List<Thing> things = getThings();
Parallel.Foreach(things, item => {
//based on some criteria, take actions from MyActionClass
MyActionClass myAct = new MyActionClass(item);
string tempstring = myAct.DoOneThing();
if(somecondition)
{
MyAct.DoOtherThing();
}
...other similar calls to myAct below here
};
}
}
And over in the MyActionClass I have something like the following:
public class MyActionClass
{
private Thing _thing;
public MyActionClass(Thing item)
{
_thing = item;
}
public string DoOneThing()
{
return _thing.GetSubThings().FirstOrDefault();
}
public void DoOtherThing()
{
_thing.property1 = "Somenewvalue";
}
}
If I can explain this any better I'll try, but I think that's the basics of my needs
EDIT:
Something else I just noticed. If I change the value of a property of the item I'm working with while inside the Parallel.Foreach (in this case, a string value that gets written to a database inside the loop), will that have any affect on the rest of the loop iterations or just the one I'm on? Would it be better to create a new instance of Thing inside the loop to store the item i'm working with in this case?
There is no shared mutable state between actions in the Parallel.ForEach that I can see, so it should be thread-safe, because at most one thread can touch one object at a time.
But as it has been mentioned there is nothing shared that can be seen. It doesn't mean that in the actual code you use everything is as good as it seems here.
Or that nothing will be changed by you or your coworker that will make some state both shared and mutable (in the Thing, for example), and now you start getting difficult to reproduce crashes at best or just plain wrong behaviour at worst that can be left undetected for a long time.
So, perhaps you should try to go fully immutable near threading code?
Perhaps.
Immutability is good, but it is not a silver bullet, and it is not always easy to use and implement, or that every task can be reasonably expressed through immutable objects. And even that accidental "make shared and mutable" change may happen to it as well, though much less likely.
It should at least be considered as a possible option/alternative.
About the EDIT
If I change the value of a property of the item I'm working with while
inside the Parallel.Foreach (in this case, a string value that gets
written to a database inside the loop), will that have any affect on
the rest of the loop iterations or just the one I'm on?
If you change a property and that object is not used anywhere else, and it doesn't rely on some global mutable state (for example, sort of a public static Int32 ChangesCount that increments with each state change), then you should be safe.
a string value that gets written to a database inside the loop - depending on the used data access technology and how you use it, you may be in trouble, because most of them are not designed for multithreaded environment, like EF DbContext, for example. And obviously do not forget that dealing with concurrent access in database is not always easy, though that is a bit away from our original theme.
Would it be better to create a new instance of Thing inside the loop to store the item i'm working with in this case - if there is no risk of external concurrent changes, then it is just an unnecessary work. And if there is a chance of another threads(not Parallel.For) making changes to those objects that are being persisted, then you already have bigger problems than Parallel.For.
Objects should always have observable consistent state (unlike when half of properties set by one thread, and half by another, while you try to persist that who-knows-what), and if they are used by many threads, then they should be already thread-safe - there should be no way to put them into inconsistent state.
And if they want to be persisted by external code, such objects should probably provide:
Either SyncRoot property to synchronize property reading code.
Or some current state snapshot DTO that is created internally by some thread-safe method like ThingSnapshot Thing.GetCurrentData() { lock() {} }.
Or something more exotic.

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

Sync Lock issue in Parallel.Foreach

I have worked with c# code for past 4 years, but recently I went through a scenario which I never pass through. I got a damn project to troubleshoot the "Index out of range error". The code looks crazy and all the unnecessary things were there but it's been in production for past 3 years I just need to fix this issue. Coming to the problem.
class FilterCondition
{
.....
public string DataSetName {get; set;}
public bool IsFilterMatch()
{
//somecode here
Dataset dsDataSet = FilterDataSources.GetDataSource(DataSetName); // Static class and Static collection
var filter = "columnname filtername"
//some code here
ds.defaultview.filter= filter;
var isvalid = ds.defaultView.rowcount > 0? true : false;
return isValid;
}
}
// from a out side function they put this in a parallel loop
Parallel.ForEach()
{
// at some point its calling
item.IsFiltermatch();
}
When I debug, dsDataSet I saw that dsDataSet is modified my multiple threads. That's why race condition happens and it failed to apply the filter and fails with index out of Range.
My question here is, my method is Non-static and thread safe, then how this race condition happening since dsDataset is a local variable inside my member function. Strange, I suspect something to do with Parallel.Foreach.
And when I put a normal lock over there issue got resolved, for that also I have no answer. Why should I put lock on a non-static member function?
Can anyone give me an answer for this. I am new to the group. if I am missing anything in the question please let me know. I can't copy the whole code since client restrictions there. Thanks for reading.
Because it's not thread safe.
You're accessing a static collection from multiple threads.
You have a misconception about local variables. Although the variable is local, it's pointing at an object which is not.
What you should do is add a lock around the places where you read and write to the static collection.
Problem: the problem lies within this call
FilterDataSources.GetDataSource(DataSetName);
Inside this method you are writing to a resource that is shared.
Solution:
You need to know which field is being written here and need to implement locking on it.
Note: If you could post your code for the above method we would be in a better position to help you.
I believe this is because of specific (not-stateless, not thread safe, etc) implementation of FilterDataSources.GetDataSource(DataSetName), even by a method call it seems this is a static method. This method can do different things even return cached DataSet instance, intercept calls to a data set items, return a DataSet wrapper so you are working with a wrapper not a data set, so a lot of stuff can be there. If you want to fine let's say "exact line of code" which causes this please show us implementation of GetDataSource() method and all underlying static context of FilterDataSource class (static fields, constructor, other static methods which are being called by GetDataSource() if such exists...)

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