This question already has answers here:
Scope of static Variable in multi-user ASP.NET web application
(4 answers)
Closed 7 years ago.
I have a problem with a static variable in ASP.NET using C#. I'm declaring the variable in a webform.
public partial class Logueado_Movimientos : System.Web.UI.Page
{
static List<ExchangeItems> theList;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostback) return;
theList = GetListValues();
}
}
So far, so good. We tested the site, no problems were found, deployed it... but in production environment something weird has happened. This site is used daily all day long and just twice, a situation has happened.
ExchangeItems has an ID property, which returns the id from the database for each item to be exchanged. The GetListValues() method is called only once when the page loads. After that, the user can select items to be exchanged by clicking on a checkbox in the GridView, make further validations and after all that, there's a "Print and Save" button, which prints to a PDF using iTextSharp and sends the status back to the database.
After all the validations, the item has been changed twice in production. For example, item 180 is the one that is being exchanged, but when the document is printed and saved, it turns out that item 103 is the one processed. All previous validations have the ID as 180. Item 103 was not even in the list to begin with.
Now, checking the database (SQL Server) we found that item 103 was saved 10 minutes after item 180. We use the GetDate() function to store the date and time. Furthermore, they were assigned to different customers by two different users.
It is possible that the user takes those 10 minutes to process the request, sometimes they are on the phone with the customer. That means that user1 is working with item 180 and user2 is working with item 103, both using the same module/webform. Since the variable is static, is it possible that both users are affecting each other's information? I'm declaring it now as "private static", just out of paranoia, but is there anything else I'm missing?
Note: the variable is static because the postback losses it's value if not declared so. It is not in the Session variable, because it is only used in that module/webform, nowhere else.
Since the variable is static, is it possible that both users are affecting each other's information?
Yes - static variables are shared across sessions. Making it private does not change that. One option may be to use a session variable instead
Session["theList"] = GetListValues();
It is not in the Session variable, because it is only used in that module/webform, nowhere else.
So? There's nothing wrong with having session data that's not used by the whole app.
Related
I am working on an app that would have a database of information. The functionality would be the user would look up entries and could save it to a personal list.
My thinking for how this would work would be that the SQLite database would have two tables, one for the information and one for the personal list.
When the user presses the button to save the info to their list a method is called that creates a personal list object and copies the info held in each field of the selected data to the identical field in the personal list object.
And so that the user knows it has been saved it appears differently like labeled that they have already been saved to the personal list. To do this that it has been saved to the list there would be a variable to keep track of that. Default like this.
var isSavedToList = false;
And when the method is called to save it to the personal list this variable is changed to true.
My question is: Can I add rows to the SQLite database (after the app has been launched and people are using it) without changing the isSavedToList variables on each users device? Since each person's list is going to be different I don't want them to be reset if I update the database with new entries.
Yes, you can. I presume you mean you're doing some kind of program update that adds new rows to the main table. Add your new rows with "isSavedToLiat" set to false (because they can't possibly be set to true because they are new and the user doesn't know about them")
Im trying working on a web app project and trying to figure out how to display my answer on the second web page.
I have put a a text box on my first webpage and have corrected the coding of my application as I have received the correct answers in the textbox after I have debugged it.
Ideally I want to remove this textbox and want my answers which I managed to display on my textbox displayed on a label in the next webpage. Here is the calculation part of my code;
var cost = ((int)duration.TotalMinutes) * 0.35m;
txtCost.Text = cost.ToString("c");
I'd like to make my answer appear in my second webpage and not have it displayed in the first. I have tried using Session["Cost"] = cost; on the button click event handler of the first webpage double cost = (double)(Session["Cost"]);
lblDisplay.Text = cost.ToString("c");
and this on the second webpage but every time I Debug it and run I always get $0.00 displayed on my label. Can someone help me fix this?
Sharing value between two views in MVC application, try following
// To save into the Cache
System.Web.HttpContext.Current.Cache["CostKey"] = cost;
// To retrieve Cache Value
var cachedValue = System.Web.HttpContext.Current.Cache["CostKey"] as double;
For Session State, have a look at this link
In ASP.NET WebForms application, you can pass data around in various ways:
Cache
See the Learning Curve answer for examples.
However, the object put in the cache is not guaranteed to be found again if the server experiences memory shortage or alike. The ASP.NET manages the cache and evicts objects on its own to maintain memory availability. This is in contrast with ApplicationState and SessionState where the objects are kept until they are removed manually, or the Application ends or Session expires.
Session and Application states
You can put any object in the SessionState object and retrieve it elsewhere in your code. However, you need to cast it appropriately as the SessionState accepts object-s. E.g. if you store a number, when you retrieving it, you must do the casting yourself, just as you already did it.
The reason it doesn't work, is perhaps you're trying to retrieve it from within another user's SessionState. Yes, the SessionState is a per-user structure. If you need to add the value as from one device and use it on another, use ApplicationState:
Application["cost"] = cost;
Redirecting Response
Using this technique, you could force the browser to request another page from the server and specify the full query string, including the variables you need. E.g. :
var destination = Server.UrlEncode("/someOtherPage.aspx?cost=34.65");
Response.Redirect(destination);
As an alternative, you can use Server.Transfer("someOtherPage.aspx") to save the roundtrip. However, in that case, the browser doesn't change the address in the address bar so the user is misled that she browses one page, but in fact, it is the someOtherPage.aspx.
I have a page which has a text box at the top. When the page is loaded, the code runs for the value of text box i.e Textbox.text= something. The logic of that code is:
bring the last value of the specific column of specific table from database (Integer always)
add 1 to it
show in text box.
It works perfectly fine. But I want to know that if two users are accessing the same page how should I handle this scenario when page is loaded.
Example the last value in DB column was 8 when the page loaded it incremented it and showed 9 in text box.
But what if two users loaded the page same time on different browsers it will cause problem because I don't want duplicate in my columns.
What you can do here is before you insert into db first get the last value from the colum and then +1 the value and then insert it into db.
but there is one catch which is if your User1 and User2 are seeing 8 value in textbox and User1 clicks on button 9 will get stored in db column and then User2 clicks on button 10 value will get stored.
Your best bet would be to load the database value into memory (e.g. a static variable) and have a method that uses a lock before incrementing and returning the result to the respective users. e.g.
private static object _syncRoot = new object();
private static int? dbValue;
public static int GetNewDbValue()
{
if (dbValue == null)
{
// load db value from database
}
// lock ensures only one user can increment at a time
lock (_syncRoot)
{
dbValue++;
return dbValue;
}
}
This will work as long as you are not running a web farm or load balancing. If you want to stay away from static, by all means you can, just make sure the object you use instead is centrally accessible.
I have an asp.net page, and a static value totalBalance that sums the values in a column in a gridview.
I found, when I refresh the page, the totalBalance get accumulated instead of keep the original value.
Is there any code I could insert so that it can refresh the values, and each time I refresh the page, it is re-calculating the column values instead of accumulating numbers?
I currently have this RemoveCache
protected void RemoveCache()
{
Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache");
Response.Expires = -1;
}
Can I insert some code in this or the aspx to reset the value after running please?
Thanks.
Never mind, I set totalBalance=0 when loading the page....
A static variable is a variable that has one copy of it (which means shared throughout the application) and its lifetime is the same as the application, once instantiated. Regardless of refresh, the variable is the same one from the first time it was created and you are re-using and re-totaling a running value. I would say stop using static variables in your web applications unless you really understand the implications and the problem should go away.
I have an ASP.Net web application that calls a customer to a station. Five employees are running this application simultaneously when they see a customer walk in they click on a ButtonGetCustomer to call the customer and come to their station.
Here is my issue. I am getting the data from SQL and storing it in a Datatable. Sometimes when two or more clerks click at the same time they call the same customer.
Any ideas in how to prevent this from happening?
I had a similar problems with thousands of people clicking the same button trying to claim a limited number of spots. Here is a similar solution:
When they click your button, run a stored procedure to mark that user as seen.
Your SPROC will first check to see if the user is marked as seen, if so, quit (I use RAISEERROR and pass a message back and catch the SQL Exception in code so you can tell them what user has already been called).
If the user hasn't been seen, the next thing your SPROC does is mark them as seen.
So the person who clicked the button either has success and sees the customer, or he gets a message saying the customer has already been seen.
The problem you are experiencing is a concurrency problem. Try wrapping the read of the datatable in a lock statement (there are several), the records you plan on returning to the calling thread should be flagged so that they are not picked up by other thread, try something like this:
private Object _syncObject = new Object();
private DataTable yourDataReadMethod() {
lock(_syncObject)
{
// Read records to return to calling thread.
// Flag records read so they are not given to other threads. You might need expiration date in case the records are not completed in a timely manner.
}
}
Furthermore, if you are updating a record after a call takes place you should compare a the db last updated date with a date that is persisted in the client form; if they differ than raise an exception, because this means that someone else has already updated the record. Hopefully that helps.