Custom Component Class question

G

Guest

Hello,

I have a fairly simple class that I created and it works great. Basically
it remembers a certain amount of strings. When a new one comes in the oldest
drops off. The problem is, when I have the test page open in multiple
browsers, they are all getting the same data. I don't want this to happen.

I have tried different uses of protected, internal, static and such with no
luck. Can anyone help me here?
 
K

Karl Seguin

Without seeing code it's impossible to tell.

Protected/Internal/Public/Private are about accessibility and have nothing
to do with the issue you have.

My guess is that you are using a static instance which is why it's shared
amongst threads.

You should be creating a new instance on each page load

sub page_load
dim myVariable as MyClass = new MyClass()
end sub

don't know what you have ...


--
MY ASP.Net tutorials
http://www.openmymind.net/ - New and Improved (yes, the popup is
annoying)
http://www.openmymind.net/faq.aspx - unofficial newsgroup FAQ (more to
come!)
 
G

Guest

Hello Karl,

True, very true. Not to mention, I could be using the wrong terms here.
Below are both the Class/Component file and then the Test app that I am
using. This is Everything...

- - - - - - - Class File:
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;

namespace NASQLStatements {
public class ThingsRemembered : System.ComponentModel.Component {
private System.ComponentModel.Container components = null;

private int iThingsToRemember;
protected internal ArrayList aThings;

public ThingsRemembered(System.ComponentModel.IContainer container) {
container.Add(this);
InitializeComponent();
aThings = new ArrayList(2);
}

public ThingsRemembered() {
InitializeComponent();
aThings = new ArrayList(2);
}

public ThingsRemembered(int iCapacity) {
InitializeComponent();
aThings = new ArrayList(iCapacity);
}

public ThingsRemembered(System.ComponentModel.IContainer container, int
iCapacity) {
container.Add(this);
InitializeComponent();
aThings = new ArrayList(iCapacity);
}

protected override void Dispose( bool disposing ) {
if( disposing ) {
if(components != null) {
components.Dispose();
}
}
base.Dispose( disposing );

iThingsToRemember = 0;
aThings.Clear(); // delete all items
aThings.TrimToSize(); // resize the array to system default

}

#region Component Designer generated code
private void InitializeComponent() {
components = new System.ComponentModel.Container();
}
#endregion

public int ThingsToRemember {
get { return iThingsToRemember; }
set {
iThingsToRemember = value;
aThings.Capacity = iThingsToRemember; // size the array
} // set
} // ThingsToRemember - Property - Read/Write

public bool AddAThing(object oThing) {
try {
if(aThings.Count == aThings.Capacity) {
aThings.RemoveAt(0); // remove the oldest one
} // if there are already the maximum number of items in the array
aThings.Add(oThing); // add the new one
return true;
} catch(Exception e) {
sLastError = e.ToString();
return false;
} // try-catch errors
} // AddAThing - Method

public string LastError {
get { return sLastError; }
} // LastError - Property - Read Only

public object LastThing() {
return aThings[aThings.Count - 1];
} // LastThing - Method

public object FirstThing() {
return aThings[0];
} // FirstThing - Method

public ArrayList AllThings {
get { return aThings; }
} // AllThings - Property - Read Only
}
}


- - - - - - - Test File:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using NASQLStatements;

namespace TestThings {
public class WebForm1 : System.Web.UI.Page {

protected System.Web.UI.WebControls.Button cmndAddThing;
protected System.Web.UI.WebControls.Button cmndShowThings;
protected System.Web.UI.WebControls.Label lablThings;

private static NASQLStatements.ThingsRemembered oStuff = new
NASQLStatements.ThingsRemembered();

private void Page_Load(object sender, System.EventArgs e) {
if(!Page.IsPostBack) {
oStuff.ThingsToRemember = 5;
lablThings.Text = oStuff.AllThings.Capacity.ToString() +
"<br>" + oStuff.AllThings.Count.ToString();
} // if this is the first time to the page
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e) {
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent() {
this.cmndAddThing.Click += new
System.EventHandler(this.cmndAddThing_Click);
this.cmndShowThings.Click += new
System.EventHandler(this.cmndShowThings_Click);
this.cmndError.Click += new System.EventHandler(this.cmndError_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void cmndShowThings_Click(object sender, System.EventArgs e) {
lablThings.Text = "" + oStuff.AllThings.Capacity.ToString() + "<br>";

for(int iPos = oStuff.AllThings.Count - 1; iPos >= 0; iPos--) {
lablThings.Text += oStuff.AllThings[iPos].ToString() + "<hr>";
} // for each item
}

private void cmndAddThing_Click(object sender, System.EventArgs e) {
Random rRandom = new Random(DateTime.Now.Millisecond);
int iValue = rRandom.Next(1, 1000);
lablThings.Text += "<br>" + oStuff.AddAThing(iValue).ToString();
}
}
}


As you can see, in the Test file I declare the Class as private static and
do a NEW. I assumed the New is necessary so it can create a New instance of
it. If it take out the Static modifier, nothing works and no random numbers
are stored. If I leave it in, it will remember the number (5) I have told
it. But so will each new web page I bring up and point to that page.

I believe you understand what I am looking for, the class to work
independantly each time it is New'd.

Please help.
--
Thanx,
Kevin

Karl Seguin said:
Without seeing code it's impossible to tell.

Protected/Internal/Public/Private are about accessibility and have nothing
to do with the issue you have.

My guess is that you are using a static instance which is why it's shared
amongst threads.

You should be creating a new instance on each page load

sub page_load
dim myVariable as MyClass = new MyClass()
end sub

don't know what you have ...


--
MY ASP.Net tutorials
http://www.openmymind.net/ - New and Improved (yes, the popup is
annoying)
http://www.openmymind.net/faq.aspx - unofficial newsgroup FAQ (more to
come!)
 
K

Karl Seguin

I think it's important that you understand this stuff, rather than I just
telling you what i think the solution is....

when you do:
private static NASQLStatements.ThingsRemembered oStuff = new
NASQLStatements.ThingsRemembered();

you are saying that there's ever only 1 instance (amongst all threads (users
or requests)) of ThingsRemembered. That is, when user 1 and user 2 hit this
page, they are accessing the same instance. Think of it, if you will, as
having this stored in the Application variable. It's worse because it isn't
thread-safe.

If you remove the static, you'll now have 1 instance per thread (or per
request). This is likely closer to what you want...but not exactly what you
want. Everytime the same user hits the button, a new instance will be
created, meaning previous things this user added will be lost. In other
words, your instance will now have the lifetime of a single request - my
guess is that's also not what you want. What you want is something in
between, it's "static" per user. To achieve this you need to store the
instance somewhere, such as the Session variable. So what you could do is:

private NASQLStatements.ThingsRemembered oStuff;

public void page_init(...)
{
oStuff = (NASQLStatements.ThingsRemembered) Session["ThingsToRemember"];
if (oStuff == null) //it'll be null the first time
{
oStuff = new NASQLStatements.ThingsRemembered();
Session.Add("ThingsToRemember", oStuff);
}
}


Hope that helps a little.

Karl

--
MY ASP.Net tutorials
http://www.openmymind.net/ - New and Improved (yes, the popup is
annoying)
http://www.openmymind.net/faq.aspx - unofficial newsgroup FAQ (more to
come!)
Grigs said:
Hello Karl,

True, very true. Not to mention, I could be using the wrong terms here.
Below are both the Class/Component file and then the Test app that I am
using. This is Everything...

- - - - - - - Class File:
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;

namespace NASQLStatements {
public class ThingsRemembered : System.ComponentModel.Component {
private System.ComponentModel.Container components = null;

private int iThingsToRemember;
protected internal ArrayList aThings;

public ThingsRemembered(System.ComponentModel.IContainer container) {
container.Add(this);
InitializeComponent();
aThings = new ArrayList(2);
}

public ThingsRemembered() {
InitializeComponent();
aThings = new ArrayList(2);
}

public ThingsRemembered(int iCapacity) {
InitializeComponent();
aThings = new ArrayList(iCapacity);
}

public ThingsRemembered(System.ComponentModel.IContainer container, int
iCapacity) {
container.Add(this);
InitializeComponent();
aThings = new ArrayList(iCapacity);
}

protected override void Dispose( bool disposing ) {
if( disposing ) {
if(components != null) {
components.Dispose();
}
}
base.Dispose( disposing );

iThingsToRemember = 0;
aThings.Clear(); // delete all items
aThings.TrimToSize(); // resize the array to system default

}

#region Component Designer generated code
private void InitializeComponent() {
components = new System.ComponentModel.Container();
}
#endregion

public int ThingsToRemember {
get { return iThingsToRemember; }
set {
iThingsToRemember = value;
aThings.Capacity = iThingsToRemember; // size the array
} // set
} // ThingsToRemember - Property - Read/Write

public bool AddAThing(object oThing) {
try {
if(aThings.Count == aThings.Capacity) {
aThings.RemoveAt(0); // remove the oldest one
} // if there are already the maximum number of items in the array
aThings.Add(oThing); // add the new one
return true;
} catch(Exception e) {
sLastError = e.ToString();
return false;
} // try-catch errors
} // AddAThing - Method

public string LastError {
get { return sLastError; }
} // LastError - Property - Read Only

public object LastThing() {
return aThings[aThings.Count - 1];
} // LastThing - Method

public object FirstThing() {
return aThings[0];
} // FirstThing - Method

public ArrayList AllThings {
get { return aThings; }
} // AllThings - Property - Read Only
}
}


- - - - - - - Test File:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using NASQLStatements;

namespace TestThings {
public class WebForm1 : System.Web.UI.Page {

protected System.Web.UI.WebControls.Button cmndAddThing;
protected System.Web.UI.WebControls.Button cmndShowThings;
protected System.Web.UI.WebControls.Label lablThings;

private static NASQLStatements.ThingsRemembered oStuff = new
NASQLStatements.ThingsRemembered();

private void Page_Load(object sender, System.EventArgs e) {
if(!Page.IsPostBack) {
oStuff.ThingsToRemember = 5;
lablThings.Text = oStuff.AllThings.Capacity.ToString() +
"<br>" + oStuff.AllThings.Count.ToString();
} // if this is the first time to the page
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e) {
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent() {
this.cmndAddThing.Click += new
System.EventHandler(this.cmndAddThing_Click);
this.cmndShowThings.Click += new
System.EventHandler(this.cmndShowThings_Click);
this.cmndError.Click += new
System.EventHandler(this.cmndError_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void cmndShowThings_Click(object sender, System.EventArgs e) {
lablThings.Text = "" + oStuff.AllThings.Capacity.ToString() + "<br>";

for(int iPos = oStuff.AllThings.Count - 1; iPos >= 0; iPos--) {
lablThings.Text += oStuff.AllThings[iPos].ToString() + "<hr>";
} // for each item
}

private void cmndAddThing_Click(object sender, System.EventArgs e) {
Random rRandom = new Random(DateTime.Now.Millisecond);
int iValue = rRandom.Next(1, 1000);
lablThings.Text += "<br>" + oStuff.AddAThing(iValue).ToString();
}
}
}


As you can see, in the Test file I declare the Class as private static and
do a NEW. I assumed the New is necessary so it can create a New instance
of
it. If it take out the Static modifier, nothing works and no random
numbers
are stored. If I leave it in, it will remember the number (5) I have told
it. But so will each new web page I bring up and point to that page.

I believe you understand what I am looking for, the class to work
independantly each time it is New'd.

Please help.
 
G

Guest

Karl,

That did the trick. Awesome. It makes sense to me now as well. Now I am
going to look into the limits of the Session object.

Take care,
Grigs/Kevin


Karl Seguin said:
I think it's important that you understand this stuff, rather than I just
telling you what i think the solution is....

when you do:
private static NASQLStatements.ThingsRemembered oStuff = new
NASQLStatements.ThingsRemembered();

you are saying that there's ever only 1 instance (amongst all threads (users
or requests)) of ThingsRemembered. That is, when user 1 and user 2 hit this
page, they are accessing the same instance. Think of it, if you will, as
having this stored in the Application variable. It's worse because it isn't
thread-safe.

If you remove the static, you'll now have 1 instance per thread (or per
request). This is likely closer to what you want...but not exactly what you
want. Everytime the same user hits the button, a new instance will be
created, meaning previous things this user added will be lost. In other
words, your instance will now have the lifetime of a single request - my
guess is that's also not what you want. What you want is something in
between, it's "static" per user. To achieve this you need to store the
instance somewhere, such as the Session variable. So what you could do is:

private NASQLStatements.ThingsRemembered oStuff;

public void page_init(...)
{
oStuff = (NASQLStatements.ThingsRemembered) Session["ThingsToRemember"];
if (oStuff == null) //it'll be null the first time
{
oStuff = new NASQLStatements.ThingsRemembered();
Session.Add("ThingsToRemember", oStuff);
}
}


Hope that helps a little.

Karl

--
MY ASP.Net tutorials
http://www.openmymind.net/ - New and Improved (yes, the popup is
annoying)
http://www.openmymind.net/faq.aspx - unofficial newsgroup FAQ (more to
come!)
Grigs said:
Hello Karl,

True, very true. Not to mention, I could be using the wrong terms here.
Below are both the Class/Component file and then the Test app that I am
using. This is Everything...

- - - - - - - Class File:
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;

namespace NASQLStatements {
public class ThingsRemembered : System.ComponentModel.Component {
private System.ComponentModel.Container components = null;

private int iThingsToRemember;
protected internal ArrayList aThings;

public ThingsRemembered(System.ComponentModel.IContainer container) {
container.Add(this);
InitializeComponent();
aThings = new ArrayList(2);
}

public ThingsRemembered() {
InitializeComponent();
aThings = new ArrayList(2);
}

public ThingsRemembered(int iCapacity) {
InitializeComponent();
aThings = new ArrayList(iCapacity);
}

public ThingsRemembered(System.ComponentModel.IContainer container, int
iCapacity) {
container.Add(this);
InitializeComponent();
aThings = new ArrayList(iCapacity);
}

protected override void Dispose( bool disposing ) {
if( disposing ) {
if(components != null) {
components.Dispose();
}
}
base.Dispose( disposing );

iThingsToRemember = 0;
aThings.Clear(); // delete all items
aThings.TrimToSize(); // resize the array to system default

}

#region Component Designer generated code
private void InitializeComponent() {
components = new System.ComponentModel.Container();
}
#endregion

public int ThingsToRemember {
get { return iThingsToRemember; }
set {
iThingsToRemember = value;
aThings.Capacity = iThingsToRemember; // size the array
} // set
} // ThingsToRemember - Property - Read/Write

public bool AddAThing(object oThing) {
try {
if(aThings.Count == aThings.Capacity) {
aThings.RemoveAt(0); // remove the oldest one
} // if there are already the maximum number of items in the array
aThings.Add(oThing); // add the new one
return true;
} catch(Exception e) {
sLastError = e.ToString();
return false;
} // try-catch errors
} // AddAThing - Method

public string LastError {
get { return sLastError; }
} // LastError - Property - Read Only

public object LastThing() {
return aThings[aThings.Count - 1];
} // LastThing - Method

public object FirstThing() {
return aThings[0];
} // FirstThing - Method

public ArrayList AllThings {
get { return aThings; }
} // AllThings - Property - Read Only
}
}


- - - - - - - Test File:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using NASQLStatements;

namespace TestThings {
public class WebForm1 : System.Web.UI.Page {

protected System.Web.UI.WebControls.Button cmndAddThing;
protected System.Web.UI.WebControls.Button cmndShowThings;
protected System.Web.UI.WebControls.Label lablThings;

private static NASQLStatements.ThingsRemembered oStuff = new
NASQLStatements.ThingsRemembered();

private void Page_Load(object sender, System.EventArgs e) {
if(!Page.IsPostBack) {
oStuff.ThingsToRemember = 5;
lablThings.Text = oStuff.AllThings.Capacity.ToString() +
"<br>" + oStuff.AllThings.Count.ToString();
} // if this is the first time to the page
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e) {
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent() {
this.cmndAddThing.Click += new
System.EventHandler(this.cmndAddThing_Click);
this.cmndShowThings.Click += new
System.EventHandler(this.cmndShowThings_Click);
this.cmndError.Click += new
System.EventHandler(this.cmndError_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void cmndShowThings_Click(object sender, System.EventArgs e) {
lablThings.Text = "" + oStuff.AllThings.Capacity.ToString() + "<br>";

for(int iPos = oStuff.AllThings.Count - 1; iPos >= 0; iPos--) {
lablThings.Text += oStuff.AllThings[iPos].ToString() + "<hr>";
} // for each item
}

private void cmndAddThing_Click(object sender, System.EventArgs e) {
Random rRandom = new Random(DateTime.Now.Millisecond);
int iValue = rRandom.Next(1, 1000);
lablThings.Text += "<br>" + oStuff.AddAThing(iValue).ToString();
}
}
}


As you can see, in the Test file I declare the Class as private static and
do a NEW. I assumed the New is necessary so it can create a New instance
of
it. If it take out the Static modifier, nothing works and no random
numbers
are stored. If I leave it in, it will remember the number (5) I have told
it. But so will each new web page I bring up and point to that page.

I believe you understand what I am looking for, the class to work
independantly each time it is New'd.

Please help.
--
Thanx,
Kevin

Karl Seguin said:
Without seeing code it's impossible to tell.

Protected/Internal/Public/Private are about accessibility and have
nothing
to do with the issue you have.

My guess is that you are using a static instance which is why it's shared
amongst threads.

You should be creating a new instance on each page load

sub page_load
dim myVariable as MyClass = new MyClass()
end sub

don't know what you have ...


--
MY ASP.Net tutorials
http://www.openmymind.net/ - New and Improved (yes, the popup is
annoying)
http://www.openmymind.net/faq.aspx - unofficial newsgroup FAQ (more to
come!)
Hello,

I have a fairly simple class that I created and it works great.
Basically
it remembers a certain amount of strings. When a new one comes in the
oldest
drops off. The problem is, when I have the test page open in multiple
browsers, they are all getting the same data. I don't want this to
happen.

I have tried different uses of protected, internal, static and such
with
no
luck. Can anyone help me here?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top