problem iterating on an empty dictionary Delphi 10.4 - dictionary

I have the following code with two dictionaries. I can see that when I iterate through DictForbidden even though it is empty the execution flow enters the loop so DictToAdd.remove(anInteger); is executed with
the old value of anInteger
var DictForbidden, DictToAdd : TDictionary<Integer,boolean>;
var anInteger: Integer;
DictForbidden := TDictionary<Integer,boolean>.Create;
DictToAdd := TDictionary<Integer,boolean>.Create;
anInteger := 1;
DictToAdd.Add(anInteger,true);
for anInteger in DictForbidden.Keys do
DictToAdd.remove(anInteger);
DictForbidden.Free;
DictToAdd.Free;
I am running Delphi 10.4 and I don't recall such a behavior in 10.3. I think back then if the dictionary was empty the loop was not entered. Do you know if this is something new on Delphi 10.4?, or maybe I am doing something wrong here?
regards, Carlos

In my 10.4.1 it doesn't enter the loop. But it may look like it does when you debug trace due to optimization made by the compiler. Try replacing the
DictToAdd.Remove
with a
writeln(anInteger) // if Console Application
ShowMessage(IntToStr(anInteger)) // if GUI Application
and see if anything is reported.

thank you very much for the quick help!
Actually you are right #Heartware. After the loop, DictToAdd still contains a 1. So basically there is no case here rather than putting a break point in the line DictToAdd.remove(anInteger); the execution is stopped and putting then the cursor above anInteger you see the value is 1 but stepping over the 1 is not being removed. When replacing the removal by a showmessage I observe the same thing the break point is reached but the showmessage is not executed.
Also noticed that when using a begin/end like this
for anInteger in DictForbidden.Keys do
begin
DictToAdd.remove(anInteger);
end;
the break point is not reached.

This is a little annoyance with the debugger caused by the fact that a loop of course produces some executable code - especially a for in loop that has calls to MoveNext and Current and some cleanup code for the enumerator after it completes.
This code has to go somewhere and often the line information being used by the debugger (aka "the blue dots") of that code overlap with actual code you wrote like in this case.
To illustrate this here is how the disassembly looks like when I put your code into a console application.
As you can see there are two breakpoints displayed here which belong to the same one breakpoint I placed in line 21. But the one that got hit is the one with the cleanup code which is responsible for destroying the enumerator. If you hit F7 and you compiled with debug dcus you will notice that it actually does not go into TDictionary.Remove but into TObject.Destroy.
Now the disassembly after placing the begin and end:
Again two breakpoints shown but this time I actually placed them both myself - and they are for different lines.

Related

Table methods not working anymore

I have a table with different methods, for example, one of them is validateWrite, when setting Field A to value X, Field B and C has to be filled in.
Suddenly (without changing code, I have compared the code with the test enviroment, it does work there) the validateWrite has stopped working.
I have tried to recompile the table, but that did not work.
Any idea why it suddenly (without making other modifications in this enviroment, or generating a CIL) stopped working and what i can try to solve it?
If some piece of code is calling table.doInsert(), it skips the validateWrite() method.
If the environments are truly identical, then I would try closing your AX client and deleting your user caches (see http://dynamics-ax-live.blogspot.com/2010/03/more-information-about-auc-file.html) where you delete all of the *.auc files located at C:\Users\[Username]\AppData\Local
In addition to what that tells you to delete, I'd also remove the *.kti file and all of the files & folders inside of C:\Users\[UserName]\AppData\Local\Microsoft\Dynamics Ax
Then open AX, see if the problem still exists. Then full system compile, CIL build, and delete your usage data.
The preferred route though would be to just drop a breakpoint in and debug the code to see what the execution stack is.

No Way to get the console handle (Dev-Pascal)

I've tried the simple program for my exercise but if i compiled, it turned give a message "No Way to get the console handle" (Dev-Pascal).
Here's my code:
program square;
uses crt;
var
side,circumference,broad:real;
begin
write('Input the side value of the square: ');
readln(side);
circumference := 4 * side;
broad := side * side;
writeln('The circumference value of the square = ', circumference);
writeln('The abroad value of the square = ', broad);
writeln();
write('Press any key...');
readkey();
end.
thank you for helping and teaching me
i would appreciate
Dev-pascal comes with a 10+ years old Free Pascal version. I really have no idea. Try to run the example on the cmdline to see if dev-pascal is the cause or something else. Temporarily disable security software might also be something to try.
I suppose, you've created a Window Skeleton project.
It has it's description: A Windows skeleton application (no window).
In this case you'll get this error though you code compiles (I've got this error too with your code).
Try to create Console Application project which has it's own description: A standard console-based (MS-DOS) application (Your code has compiled and the program worked as well).
P.S. Can't say what exactly happens -- couldn't find any documentation about errors in Dev-Pas (1.9.2).
My assumption is that skeleton program doesn't imply console window for execution program while console application does.
just close the project and then re-open the pascal source file (.pas). And maybe put "readln;" just before "END.".

Lotus Notes #formula language: Order of Actions wrong?

I have defined an action with the following two commands:
#Prompt([...]; "1");
#Command([ToolsRunMacro];"(AGENT)");
#Prompt([...]; "2");
#If(#GetProfileField("PrivateProfile";"LENGTH";#UserName))>0;#PostedCommand([Compose];"FORM");"");
#Prompt([...]; "3");
But with the #Prompt commands I found out, that first of all each of the #Promptmessages (1-3) are displayed and after that the AGENT runs. But as the AGENT manipulates the LENGTHfield, the #IF statement compares an 'obsolete' value.
Maybe each statement is executed at once? If yes: how can I prevent the agent from this behavior?
I would appreciate any help!
The [ToolsRunMacro] command will always run after all #Functions have executed first. There is no way to change this.
You can get a list of what commands will execute straight away vs after other functions that execute at the end, in the infocenter documentation.
http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/topic/com.ibm.designer.domino.main.doc/H_COMMAND.html
Also something to be aware on your code is that Profile documents are cached. So you might not in all cases see any changes made to the document straight away.

SqlSiteMapProvider - OnSiteMapChanged event never fires?

I'm doing the Wicked Code implementation of SqlSiteMapProvider, except in VB.NET.
There's a few things with the code that are causing issues, and I don't understand how it is supposed to work the way it's written in the article. I've provided the code straight from the article provided below. I've pasted the code here for ease of viewing
First issue - the depedency is instantiated BEFORE (lines 134-137) the tree is created (151-160) - so as soon as you add the depedency to the http.cache (165-167), the OnSiteMapChanged event (242) fires immmediately - making the entire proccess run again - and this loops many times until finally something makes it stop. (i stepped through it and counted the code looping at least 20 times before I gave up on trying to guess when it hit last)
OK, so to fix this I just moved the code to the create the dependency to AFTER the tree is built, right before inserting to http.cache (so HasChanged property is false when adding to http.cache, and you don't get stuck in this psuedo-ifinite-loop).
I still have a problem though - every time a page loads, the BuildSiteMap() hits and line 121 checks if _root is not null - it seems it is never null after it is first built... this is good because I don't want to hit the DB each time. Now, I insert a record into the table... the OnSiteMapChanged event never fires. As I browse pages on the app, the sitemap does not reflect the newly inserted record - stepping through the code, I see that the check at line 121 is still causing the function to short circuit... The sitemap will only refresh if i re-start Visual Studio, which causes the private _root field to become null again, and re-builds the sitemap, reflecting the new changes.. (refreshing the browser or starting new browser instances does not work)...
EDIT: THE ISSUE STEMMED FROM A SILLY 'SET NOCOUNT ON' LINE IN THE TOP OF MY STORED PROC. APPARENTLY THIS BREAKS THE QUERY NOTIFICATION. It seems that this statement is seen as a result set and that the second, actual query statement invalidates the result set resulting in a notification. This was very hard to find and nowhere in the MSDN documentation until I added the comment. Hope this saves someone else the miser I went through!
THE ISSUE STEMMED FROM A SILLY 'SET NOCOUNT ON' LINE IN THE TOP OF MY STORED PROC. APPARENTLY THIS BREAKS THE QUERY NOTIFICATION. It seems that this statement is seen as a result set and that the second, actual query statement invalidates the result set resulting in a notification. This was very hard to find and nowhere in the MSDN documentation until I added the comment. Hope this saves someone else the miser I went through!

"Failed to enable constraints" Error keeps cropping up (seemingly randomly) in my ASP.Net project

I have a weird problem where the "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints." error sometimes pops up when I am trying to build my project.
The line in question throwing the error was auto-generated code in the designer file for the dataset. To find out the offending table, I used the following code:
Try
Me.Adapter.Fill(dataTable) <--Breakpoint here on the offending line
Catch ex As Exception
For Each TRow As DataRow In dataTable.Rows
If TRow.HasErrors Then
Trace.Write(TRow.RowError)
End If
Next
End Try
Funnily enough, as soon as I run the project after putting in the above code and breakpoint, the error disappears. I assume this has something to do with the code being regenerated. All data is presented successfully, and the project compiles without errors.
However, this has happened often enough for me to frustrate me. Anybody know what might be causing the error and how I can isolate it?
What unique constraint are you placing on the datatable and have you verified that the data your passing in doesn't have any duplicates? If this is coming from a shared database perhaps someone else is modifying the data which could be causing the randomness.
Edit
If that code is exactly as what you have (And forgive me my vb.net is not as strong as my C#). Wouldn't it swallow the exception? In C# we need to rethrow the error.
Add a Trace.Write() right before you go into your for loop.
You are probably working with a typed dataset, or have some code configuration on it. Also you might be reading from one table, and then adding data from another.
In any of those cases, you really want to look into any inconsistencies between the schema. If it is a typed dataset / or configured in code, check its definition, and look for anything different from the sql table. If you are reading from 2 different tables, check the definition of both tables.
Figured it out finally!
The reason the breakpoint wasn't being hit was because the code in question was auto-generated, and had the attribute "DebuggerNonUserCodeAttribute". In addition, in my VS settings, I had set the debugger to "Just my code".
When I ran the code again, and the breakpoint wasn't hit, I noticed the breakpoint icon had changed to a warning. Hovering showed this:
"The breakpoint will currently not be hit. Breakpoints cannot be set in a method or class with the 'DebuggerNonUserCode' attribute when the debugger option 'Just My Code' is enabled."
Ouch!
Once I had removed the "Just My Code" debugging option, the breakpoint was hit, and I discovered that one of the rows had a NULL value in one of the columns which had a non-null constraint. Stupid ole' me!
You should use this code before you fill DataTable :
var dt = new System.DataTable.DataTable();
dt.Clear();
dt.Rows.Clear();
dt.Columns.Clear();

Resources