ASP.Net session start and end issue - c#

I am using ASP.Net + .Net 3.5 + VSTS 2008 + IIS 7.0 + C# to develop a web application. I am creating a very simple web application, and I just modified page_load, Session_Start and Session_End. Here are my code, my question is I find session ends message is written to file immediately after session start message. My test method is just open IE to access this page. I think session should last for a long time, like several mins. Why session ends so quickly? Why seesion ends even if I do not close the page?
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Hello World! ");
Session["SomeUserData"] = DateTime.Now;
}
protected void Session_Start(object sender, EventArgs e)
{
using (TextWriter tw = new StreamWriter(#"C:\TestSession\bin\session.txt", true))
{
// write a line of text to the file
tw.WriteLine(DateTime.Now + " Session Started.");
}
}
protected void Session_End(object sender, EventArgs e)
{
using (TextWriter tw = new StreamWriter(#"C:\TestSession\bin\session.txt", true))
{
// write a line of text to the file
tw.WriteLine(DateTime.Now + " Session Ended.");
}
}
I met with the same issue even if add Session manipulation code into Page_Load method, here is output file content, which you can see session ends event is called immediately after session start.
2010/7/15 0:11:14 Session Started.
2010/7/15 0:11:14 Session Ended.
2010/7/15 0:11:28 Session Started.
2010/7/15 0:11:28 Session Ended.
thanks in advance,
George

If I remember correctly, you need to actually assign something to Session to activate it. Otherwise ASP.NET will regenerate a new session (new session id if you use fiddler to check) every time.
EDIT: Because session.txt is located inside the bin directory. Once you write to the bin directory the application will restart so the Session_End event fired immediately. Move session.txt out of bin directory to somewhere else will resolve your issue.

This kind of behaviour is sometimes caused by an overzealous anti-virus program. Try disabling the anti-virus and see if that helps. If it helped, then add the site's directory to the exclusion list.
Also closing the browser doesn't have any effect on your session either way.

Related

how to count number of visitors for website in asp.net c#

How do I count the number of visitors for website in asp.net c#?
I am using the code below:
In global.asax page:
<%# Application Language="C#" %>
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
Application["NoOfVisitors"] = 0;
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Application.Lock();
Application["NoOfVisitors"] = (int)Application["NoOfVisitors"] + 1;
Application.UnLock();
}
In .aspx page:
<asp:Label runat="server" ID="lbluser" />
In .aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
lbluser.Text = Application["NoOfVisitors"].ToString();
}
The application counter is resetting to 0 every one hour ...
Where have I erred in counting the number of users?
Application State is volatile. Check the this MSDN articule:
When using application state, you must be aware of the following
important considerations:
...
Volatility Because application state is stored in server memory, it
is lost whenever the application is stopped or restarted. For example,
if the Web.config file is changed, the application is restarted and
all application state is lost unless application state values have
been written to a non-volatile storage medium such as a database.
So you should not use that for saving this kind of data that you want to persist over time. Because applications pools get reseted from time to time. And I suspect you don't want to reset your visitor count when that happens.
You'll need some kind of data store which can persist your data when you application is not running.
Here are some choices:
File (XML, JSON, plain text, etc.): sample xml code for visitors counter
Database (SQL Server, SQLite, etc.): sample database code for hit counter
In global.asax file under this method
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Application.Lock();
Application["NoOfVisitors"] = (int)Application["NoOfVisitors"] + 1;
Application.UnLock();
}
then in your page load please add
lblCount.Text = Application["NoOfVisitors"].ToString();
then you can get the number of visitors on your site .
If your application is hosted in IIS and has an application pool, you can check the Application Pool Recycling Settings. Depending on your version, the default is 1740 or 29 hours. Maybe the pool for your application is configured to 60 or around that value? The next setting to check is the Idle Time Out. I believe its default value is 20 on a new server. You can set this to 0. I recommend you read about these settings prior to changing them.
The only possible reason reason could be that, have you hosted your application on a third party server? if yes, it could be that the provider might be killing your application. i have numerous cases where these providers kill your application depending on their memory management schemes.
Simple store the visitor count after changing its value to database and on application start load this value from database that's all you have to do.
You should save count for visits on fly on an xml file under root directory. Check following blog for complete steps :How to count number of visitors in asp.net website
If you want to manage visitor on code level you need to start visitor counter under Application_Start method in application configuration file after need to increase the counter on every session. For more details follow the link given below.
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Application.Lock();
Application["NoOfVisitors"] = (int)Application["NoOfVisitors"] + 1;
Application.UnLock();
}
http://www.freshcodehub.com/Article/49/show-number-of-visitors-in-aspnet-application
Application Pool Restart periodically default settings is 60 minutes.
when app pool restart the count restart as well.

Custom WebPart Timing out after 5 minutes exactly

I have a SharePoint 2010 webpart that is timing out after 5 minutes when on the QA servers. The QA environment is 1 web server, 2 app servers, and a SQL server. I've tried EVERYTHING to fix this. Changed the IIS timeouts, worker failures, disabled ping checks and nothing works. It's the simplest code in the world!!
Could someone please try this on one of your environments? Preferably one with multiple servers making up the farm. This code works perfectly on our dev servers which is just one box. All I am doing is calling the SPLongOperation, sleeping for 6 minutes, and ending the long operation.
Anyone have a clue what I'm missing?
Code:
protected void btnTest_Click(object sender, EventArgs e)
{
string currentUrl = SPContext.Current.Web.Url;
using (SPLongOperation operation = new SPLongOperation(this.Page))
{
operation.LeadingHTML = "Updating Reports on Selected Project Sites";
operation.TrailingHTML = "Gathering the worker threads, this could take a second. Please stand by...";
operation.Begin();
Thread.Sleep(360000);
operation.End(currentUrl, SPRedirectFlags.Default, this.Context, "");
}
SetStatus("Slept for a long time!", false);
}
Interestingly, if I run the below operation where I don't navigate to the long operation page, it makes me re-authenticate but then redirects me to the "Internet Explorer cannot display the webpage" screen. Very odd.
protected void btnTest2_Click(object sender, EventArgs e)
{
SetStatus("Before Sleep", false);
Thread.Sleep(360000);
SetStatus("Sleep Successful!", false);
}

How to detect when a page is being update to IIS

Whenever I update my web app on IIS, any user who currently using it, will see the page be unresponsive and it won't work again until they refresh the browser. (The update process last for about 30 seconds)
I would like to show up a notification, such as a javascript alert, for user to know that the page is being udpated and please try to refresh the page after 30 seconds, etc.
I tried to catch the Exception in Global.ascx but no exception was thrown in this case.
Consider using app_offline.htm. It is a page that will cause clients to see your IIS app as being down. When you're through updating, just remove the page.
You could create a FileSystemWatcher in global.ascx then bubble up (update a js for instance) an exception when a file is updated. You could start with this:
using System.IO;
namespace WebApplication1
{
public class Global : System.Web.HttpApplication
{
FileSystemWatcher watcher;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
watcher = new FileSystemWatcher(this.Context.Server.MapPath("/"));
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
}
void watcher_Changed(object sender, FileSystemEventArgs e)
{
//set a value in js file
FileInfo jsFilesChanged = new FileInfo(Path.Combine(this.Context.Server.MapPath("/"), "scripts", "files_changed.js"));
using (StreamWriter jsWriter = (!jsFilesChanged.Exists) ? new StreamWriter(jsFilesChanged.Create()) : new StreamWriter(jsFilesChanged.FullName, false))
{
jsWriter.WriteLine("var changed_file = \"" + e.Name + "\";");
}
}
//.......
}
}
Then in client code include files_changed.js and create a periodic timeout call to check the var changed_file. Also, make sure watcher doesn't get garbage collected.
Some references:
http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx
http://www.developerfusion.com/article/84362/extending-filesystemwatcher-to-aspnet/
How the big boys do this:
You need to have a way of posting an alert on a page. Typically this is done by having a table in your database for these alerts. Basically you are just storing some text in there like "hey, the site is going down for maintenance between 8:00am and 8:01am"..
On each page load, you check that table and display any messages found in a conspicuous place (like the top).
Prior to pushing an update you add the alert, while giving them enough time to wrap up whatever it is that they are doing.
After the push is complete you clear out the alerts table.
Honestly the main issue you have is simply one of scheduling updates and communicating to the users what's about to happen. You want to do so in a way that isn't a surprise. That said, you might consider enabling the optimizeCompilations flag in order to try and speed up the compilation time of your website when it is first hit after pushing an update.

How to poll a directory in ASP.NET?

I want to poll a directory to check whether new file is added to the directory in ASP.NET web application (C#). If any new file is added I want to read that file.
Can anybody give me an idea how to do that?
Thanks.
Normally you would use the FileSystemWatcher class. However, you have another problem. A web application isn't really suited for background processes. You can get away with it by using a background task and threading in general, but it's probably not a good idea. Always assume that your web application is stateless and can be re-started by the server at any time.
Ask yourself:
What is going to trigger this polling?
How is the application going to respond to this polling?
A web application is essentially a request/response system. Thus, any server-side logic (such as the polling) should be triggered by a request. But once the response is given, what is going to become of the polling? Suppose you fork off a thread in the web application which will poll in the background. What is it going to do when it finds something? There's no request/response interacting with it at that point.
Could this polling perhaps be delegated to another application? Perhaps a Windows Service? Then, in response to finding something during the polling, it can modify values in the web application's database. That way future requests to the web application would see the updated state.
This would more cleanly separate the concerns on an architectural level.
you can use FileSystemWatcher and create the instance in Application_Start event.
Sample code:
protected void Application_Start(
Object sender, EventArgs e)
{
FileSystemWatcher fsw =
new FileSystemWatcher(
Server.MapPath( “.” ) );
Application.Add( “myfsw” , fsw );
// Add event handlers here
fsw.EnableRaisingEvents = true;
}
Dispose this when application ends.
protected void Application_End(
Object sender, EventArgs e)
{
FileSystemWatcher fsw =
(FileSystemWatcher
)Application[“myfsw”];
Application.Remove( “myfsw” );
fsw.Dispose();
}
First after your program loads check the directory content and keep it as a list.After that add a timer. The timer will check the content of the directory and compare the current content with the last logged content. After comparing you can see which files are changed in the directory.
you can change the frequency of the timer based on your needs.
Hope it helps.
edit:
call GetDirectoryContent(); in your program's onload.
FileInfo[] lastUpdatedFies;
FileInfo[] temporaryFiles;
private void GetDirectoryContent()
{
DirectoryInfo di = new DirectoryInfo("c:/mydirectorypath/");
lastUpdatedFies = di.GetFiles(".");
}
private void GetDirectoryContent()
{
DirectoryInfo di = new DirectoryInfo("c:/mydirectorypath/");
lastUpdatedFies = di.GetFiles("*.*");
}
protected void tmrDirectory_Tick(object sender, EventArgs e)
{
DirectoryInfo di = new DirectoryInfo("c:/mydirectorypath/");
temporaryFiles = di.GetFiles("*.*");
foreach (FileInfo f in lastUpdatedFies)
{
//compare the list of files and do whatever you want.
// you can track any kind of data this way.
}
}`
you can also adjust the timer frequency. In this example i just kept track of files.so you will learn only if a file is deleted or added. if you want to keep track of the file size you can also do it in the same way.
Add Filewatcher in global.asmx when the application start event.
It's not clear, what do you want to do with these files. If you want read these files and cache them for future output, you can use ASP.NET Cache with CacheDependency on specific directory and a callback which will re-read the directory and add new file to cache. You should take a look at Cache.Insert method and CacheDependency constructor

ASP.NET FileSystemWatcher Changed Event

I created a ASP.NET Website with Visual Studio 2010 C#.
My program reads a config file to create some classes and display informations.
The config file is not included in the project (does not appear in the solution explorer). If I modify the file while my application is not running, and run it afterwards, it still reads the old version like it keep it in cache. I have to close Visual Studio for it to accept the changes.
My second problem is related to (if not caused by) my first problem. I am using FileSystemWatcher to see if the config file is modified while the application is running, but the Changed event is never called.
private string _configFilePath;
private FileSystemWatcher _watcher;
protected void Page_Load(object sender, EventArgs e)
{
//Gets the config file in the application's parent directory
string appPath = this.MapPath("~");
string[] split = appPath.Split('\\');
_configFilePath = appPath.Substring(0, appPath.Length - split[split.Length-1].Length);
Application.Add("watcher", new FileSystemWatcher(_configFilePath.Substring(0, _configFilePath.Length-1), "*.xml"));
_watcher = (FileSystemWatcher)Application["watcher"];
_watcher.NotifyFilter = NotifyFilters.FileName;
_watcher.Changed += new System.IO.FileSystemEventHandler(Watcher_Changed);
_configFilePath += "ProductsConfig.xml";
UpdateDisplay();
}
private void Watcher_Changed(object source, FileSystemEventArgs e)
{
UpdateDisplay();
}
How can I solve this?
Thank you
My second problem is related to (if not caused by) my first problem. I
am using FileSystemWatcher to see if the config file is modified while
the application is running, but the Changed event is never called.
It's never called because at that point the Thread that's servicing the request is already returned to the pool and the request has ended. The Watcher_Changed event will never fire.
You need to tackle this in a different manner, remember that HTTP is a "disconnected" protocol, after the request has been served, don't expect any of the page events to fire "automagically" when something happens on the server side that would notify all connected users.
One way to do this is via Ajax. You'd need to constantly "ask" the server whether there's new information or not and update the sections of the page that need to be updated as a result of the change on the server.
There are 2 problems here.
1. You never called _watcher.EnableRaisingEvents = true;
2. You try to go to the parent folder of your root folder, which might not be allowed.
/ Tibi

Categories

Resources