Access Session/ViewState Multiple Times in a Scope - c#

When using Session property, a set/get would be written either as the following:
public int MySessionPro
{
get
{
return Session["MySessionKey"] == null ? 0 : Convert.ToInt32(Session["MySessionKey"]);
}
set
{
Session["MySessionKey"] = value;
}
}
Or as the following:
public int MySessionPro
{
get
{
object mySessionPro = Session["MySessionKey"];
return mySessionPro == null ? 0 : Convert.ToInt32(mySessionPro);
}
set
{
Session["MySessionKey"] = value;
}
}
What is more efficient/better perfomance? The first approach of the second?
The same exact question applies by replacing every "Session" with "ViewState" in the code above. Again, are the two approaches different in term of efficency?

Either with a ViewState or a Session the answer is the same: the difference in performance will be very small, unless you have a lot of variables in your ViewState or Session object.
In your first approach, you will query for your variable 1 times more than in the second.
In the second, you just have one more variable you set.
Since querying for your variable takes more operations than just setting an extra variable, the second approach should be more efficient/better than the first one.

Related

Should the value of a property be updated with a method or determined in the getter?

Just a quick question so as to know if there is a better practice between updating the value of a property with a method that gets called everytime the value needs to be changed or just to do it in the getter.
For instance between this:
public double Balance { get; private set; }
private void UpdateBalance()
{
if (Payments.IsNullOrEmpty())
{
Balance = 0;
}
else
{
double amountSum = 0;
foreach (Payment payment in Payments)
{
amountSum += payment.Amount;
}
Balance = amountSum;
}
}
And this :
public double OtherBalance
{
get
{
if (Payments.IsNullOrEmpty())
return 0;
double amountSum = 0;
foreach (Payment payment in Payments)
{
amountSum += payment.Amount;
}
return amountSum;
}
}
The only difference I can think of is one of performance, since in the first case the getter runs through the whole list every time we try to get the value of the property. However, you don't need to worry about calling the Update method every time you do a change that might impact the value of the property like in the second option. Is that difference really significant ? Beyond that, is there any reason to chose one option over another ?
Thanks in advance
Well in first method for reading the balance you should call the getter again and in the second method there is no balance at all, personally I prefer second method because it's generate the value at the call time so you can be sure that it is always updated and it doesn't need to call a function and then read the value so it's cleaner and more maintainable.
To add to Kiani's answer, if you don't mind using Linq, you could turn your code to a one liner.
private double Balance=>(!Payments.Any())?0:Payments.Sum(t=>t.Amount);

Do references to collections cause any trouble with threads?

I have something like the following code:
public class MainAppClass : BaseClass
{
public IList<Token> TokenList
{
get;
set;
}
// This is execute before any thread is created
public override void OnStart()
{
MyDataBaseContext dbcontext = new MyDataBaseContext();
this.TokenList = dbcontext.GetTokenList();
}
// After this the application will create a list of many items to be iterated
// and will create as many threads as are defined in the configuration (5 at the momment),
// then it will distribute those items among the threads for parallel processing.
// The OnProcessItem will be executed for every item and could be running on different threads
protected override void OnProcessItem(AppItem processingItem)
{
string expression = getExpressionFromItem();
expression = Utils.ReplaceTokens(processingItem, expression, this);
}
}
public class Utils
{
public static string ReplaceTokens(AppItem currentProcessingItem, string expression, MainAppClass mainAppClass)
{
Regex tokenMatchExpression = new Regex(#"\[[^+~][^$*]+?\]", RegexOptions.IgnoreCase);
Match tokenMatch = tokenMatchExpression.Match(expression)
if(tokenMatch.Success == false)
{
return expression;
}
string tokenName = tokenMatch.Value;
// This line is my principal suspect of messing in some way with the multiple threads
Token tokenDefinition = mainAppClass.TokenList.Where(x => x.Name == tokenName).First();
Regex tokenElementExpression = new Regex(tokenDefintion.Value);
MyRegexSearchResult evaluationResult = Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).FirstOrDefault();
string tokenValue = string.Empty;
if (evaluationResult != null && evaluationResult.match.Groups.Count > 1)
{
tokenValue = evaluationResult.match.Groups[1].Value;
}
else if (evaluationResult != null && evaluationResult.match.Groups.Count == 1)
{
tokenValue = evaluationResult.match.Groups[0].Value;
}
expression = expression.Replace("[" + tokenName + "]", tokenValue);
return expression;
}
}
The problem I have right now is that for some reason the value of the token replaced in the expression get confused with one from another thread, resulting in an incorrect replacement as it should be a different value, i.e:
Expression: Hello [Name]
Expected result for item 1: Hello Nick
Expected result for item 2: Hello Sally
Actual result for item 1: Hello Nick
Actual result for item 2: Hello Nick
The actual result is not always the same, sometimes is the expected one, sometimes both expressions are replaced with the value expected for the item 1, or sometimes both expressions are replaced with the value expected for the item 2.
I'm not able to find what's wrong with the code as I was expecting for all the variables within the static method to be in its own scope for every thread, but that doesn't seem to be the case.
Any help will be much appreciated!
Yeah, static objects only have one instance throughout the program - creating new threads doesn't create separate instances of those objects.
You've got a couple different ways of dealing with this.
Door #1. If the threads need to operate on different instances, you'll need to un-static the appropriate places. Give each thread its own instance of the object you need it to modify.
Door #2. Thread-safe objects (like mentioned by Fildor.) I'll admit, I'm a bit less familiar with this door, but it's probably the right approach if you can get it to work (less complexity in code is awesome)
Door #3. Lock on the object directly. One option is to, when modifying the global static, to put it inside a lock(myObject) { } . They're pretty simple and straight-foward (so much simpler than the old C/C++ days), and it'll make it so multiple modifications don't screw the object up.
Door #4. Padlock the encapsulated class. Don't allow outside callers to modify the static variable at all. Instead, they have to call global getters/setters. Then, have a private object inside the class that serves simply as a lockable object - and have the getters/setters lock that lockable object whenever they're reading/writing it.
The tokenValue that you're replacing the token with is coming from evaluationResult.
evaluationResult is based on Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).
You might want to check GetRegexMatches to see if it's using any static resources, but my best guess is that it's being passed the same currentProcessingItem value in multiple threads.
Look to the code looks like that splits up the AppItems. You may have an "access to modified closure" in there. For example:
for(int i = 0; i < appItems.Length; i++)
{
var thread = new Thread(() => {
// Since the variable `i` is shared across all of the
// iterations of this loop, `appItems[i]` is going to be
// based on the value of `i` at the time that this line
// of code is run, not at the time when the thread is created.
var appItem = appItems[i];
...
});
...
}

Database queries in Entity Framework model - variable equals zero

I have some problems with using database in my Model. I suspect that its not good idea to use database queries in Model, but I don't know how to do it better.
Code:
Let's assume that I have some application to analize football scores. I have some EF model that stores info about footballer:
public class Player
{
[...]
public virtual ICollection<Goal> HisGoals { get; set; }
public float Efficiency
{
get
{
using(var db = new ScoresContext())
{
var allGoalsInSeason = db.Goals.Count();
return HisGoals.Count / allGoalsInSeason;
}
}
}
}
Problem:
So the case is: I want to have a variable in my model called "Efficiency" that will return quotient of two variables. One of them contains data got in real-time from database.
For now this code doesn't work. "Efficiency" equals 0. I tried to use debugger and all data is correct and it should return other value.
What's wrong? Why it returns always zero?
My suspicions:
Maybe I'm wrong, I'm not good at C#, but I think the reason that Efficiency is always zero, is because I use database in it and it is somehow asynchronous. When I call this variable, it returns zero first and then calls the database.
I think that your problem lies in dividing integer / integer. In order to get a float you have to cast first one to float like this:
public float Efficiency
{
get
{
using(var db = new ScoresContext())
{
var allGoalsInSeason = db.Goals.Count();
return (float)HisGoals.Count / allGoalsInSeason;
}
}
}
Dividing int/int results always in int that is in your case 0 (if it is as you said in comment 4/11).
Second thing is that Entity Framework will cache values - test it before shipping to production.

Universal method for setting ViewState/Session for passed variable and value?

What I have now is code for setting ViewState or Session of desired variable:
if (ViewState["currentPage"] != null)
{
currentPage = Convert.ToInt32(ViewState["currentPage"].ToString());
}
else
{
currentPage = 0;
ViewState["currentPage"] = currentPage.ToString();
}
currentPage field is global with default value of zero in CodeBehind (public int currentPage = 0;) and therefore its initial value is zero whenever the page is loaded. So I wrote these few lines to save its last value. Just to mention that wherever currentPage value is changed in CodeBehind, I added
"ViewState["currentPage"] = currentPage.ToString();" in line after.
What I want is universal function that takes two arguments, variable and value, for setting ViewState according to code above. So if necessary, I can just call method, something like that: setViewState(currentPage, 0)
is there a need for you to have the variable as an input parameter - what is wrong with simple creating a function in a class somewhere in your application and passing the value in then returning the created value ? i.e.
public int setViewState(int value) {
//return and set value here?
}
so would be used like currentValue= setViewState(50);
I think the difficulty you are going to have with a global function is that ViewState is local to the page.
A couple of things that might help you though:
Don't forget ViewState is an object so you don't have to do the ToString
You could put the necessary code in a Property like this:
public int? TestInt {
get { return ViewState["TestInt"] as int?; }
set { ViewState["TestInt"] = value; }
}
I like this approach because its very obvious what the code is doing, particuarly as I try to minimize ViewState usage where possible.

Unassigned variable in return statement

for some reason I don't seem to be able to put the return in a fashion that captures this stored procedure's return value (0 or -1), either it returns the value which was used to initialize the variable or keeps telling me the local variable is unassigned.
public int changePass(int idUsuario, String old_pass, String new_pass)
{
int result;
try
{
DataTable tablaResultado =
DataBaseAccess.advanceStoredProcedureRequest(
"pa_usuario_change_pass",
new SPP[]
{
new SPP("id_usuario", idUsuario.ToString()),
new SPP("old_pass", old_pass.ToString()),
new SPP("new_pass", new_pass.ToString())
});
if (tablaResultado.Rows.Count > 0)
{
if (tablaResultado.Rows[0] != null)
{
result = (int.Parse(tablaResultado.Rows[0].ItemArray[0].ToString()));
}
}
return result;
}
catch (System.Data.SqlClient.SqlException sqlException)
{
throw sqlException;
}
}
I have multiple methods which follow the same pattern and all of those works, I have been trying to get this to work for awhile now, and I'm sure I'm overlooking something very, very obvious. Either way I cannot find it right now so I was hoping someone could refresh my memory or give me a tip.
The code only assigns a value to the result variable if two different conditions both happen to be true. That is, if the row count is > 0 and the first row is non-null. The compiler is telling you, completely legitimately, that your code contains a path to the return statement where the variable being used hasn't been assigned a value yet.
You need to decide what the method should return if either of those conditions are not true, and then assign that value to the result variable as part of its initialization.
EDIT:
To be clear: it seems you may be overlooking the possibility that your code won't successfully execute the stored procedure. But it can only return a value to be assigned to result when those two conditions are true. You either need to pick a default value that is reasonable to return when one or the other of the conditions aren't true, or you need to fix the code so that those conditions are always both true (and so the SP always executes successfully).

Categories

Resources