views:

231

answers:

3
+1  A: 

A static object is shared across all instances of an application so if you alter the value of a static object, that alteration will be reflected across all instances of the application which access that object. Therefore if your web profile is reassigned by another thread (i.e. a second user visiting a page) inbetween you setting it for the current user, it will contain information different to what you expect.

To get around this your code should look something like:

public WebProfile p = null;

protected void Page_Load(object sender, EventArgs e)
{
    p = ProfileController.GetWebProfile();
    if (!this.IsPostBack)
    {
         PopulateForm();
    }       
}

public static WebProfile GetWebProfile()
{
    //get shopperID from cookie
    string mscsShopperID = GetShopperID();
    string userName = new tpw.Shopper(Shopper.Columns.ShopperId,        mscsShopperID).Email;
    return WebProfile.GetProfile(userName); 
}

Note that the static object has not been set and the returned value should be assigned to a NON STATIC instance of the web profile class in your calling method.

Another option is to LOCK your static variable for the whole time it is in use but this will lead to severe degradation in performance as the lock will block any other requests for the resource until the current locking thread is completed - not a good thing in a web app.

Wolfwyrd
A: 

@Wolfwyrd: Thank you for your quick and detailed response -- I really appreciate it.

The reason I changed WebProfile object to a static object was because I need to access the profile object within a [WebMethod] (called from javascript on the page). Is there a way to access a profile object within a [WebMethod]? If not, what choices do I have?

Thanks again.

Geri Langlois
+1  A: 

@Geri

If the profile doesn't often change for the user you have the option of storing it in the current Session state. This will introduce some memory overhead but depending on the size of the profile and the number of simultaneous users this could well be a non-issue. You'd do something like:

public WebProfile p = null;
private readonly string Profile_Key = "CurrentUserProfile"; //Store this in a config or suchlike

protected void Page_Load(object sender, EventArgs e)
{
    p = GetProfile();

    if (!this.IsPostBack)
    {
        PopulateForm();
    }       
}

public static WebProfile GetWebProfile() {} // Unchanged

private WebProfile GetProfile()
{
    if (Session[Profile_Key] == null)
    {
        WebProfile wp = ProfileController.GetWebProfile();
        Session.Add(Profile_Key, wp);
    }
    else
        return (WebProfile)Session[Profile_Key];
}

[WebMethod]
public MyWebMethod()
{
    WebProfile wp = GetProfile();
    // Do what you need to do with the profile here
}

So that the profile state is retrieved from session whenever necessary and should get around the need for static variables.

Wolfwyrd