asp.net timer not working - asp.net

I am new to aspx and can not get my web timer to work. What am I missing here? Also DebugSet.logoutTime = 1800000 and DebugSet.logotWarnings = 3. The user is to be warned every minute before they are logged out of the system. These settings will be raised before the release, I just lowered them for testing purposes.
public partial class test : System.Web.UI.Page
{
private LoggedUser _User;
private Timer LogoutTimer;
private int TmCnt = 0;
protected void Page_Load(object sender, EventArgs e)
{
_User = new LoggedUser(true);
SetTimer();
}
private void SetTimer()
{
LogoutTimer = new Timer();
LogoutTimer.Interval = DebugSet.logoutTime/DebugSet.logoutWarnings;
LogoutTimer.Tick += new EventHandler<EventArgs>(LogoutTimer_Tick);
LogoutTimer.Enabled = true;
LogoutTimer.ViewStateMode = ViewStateMode.Enabled;
}
private void LogoutTimer_Tick(object sender, EventArgs e)
{
TmCnt++;
if (TmCnt == DebugSet.logoutWarnings)
{
_User.UserLoggedIn = false;
_User.SetSessions();
LogoutTimer.Enabled = false;
HttpContext.Current.Session["FCSWarning"] = "LoggedOut";
Response.Redirect("../Views/index.aspx");
}
else
{
int i = (DebugSet.logoutTime / (1000 * 60)) - ((DebugSet.logoutTime / (1000 * 60)) * TmCnt);
string msg = "<Script language=javascript>alert('You will be logged out in " + i.ToString() + " min. due to inactivity.');</Script>";
Response.Write(msg);
}
}
}

The ASP.NET Timer is an ASP.NET control. Each ASP.NET control must be added into a page control hierarchy, otherwise, it won't operate correctly or won't operate at all.
Add your Timer to page control hierarchy:
LogoutTimer = new Timer();
LogoutTimer.ID = "MyTimer";
this.Controls.Add(LogoutTimer);
LogoutTimer.Interval = DebugSet.logoutTime/DebugSet.logoutWarnings;
...

You are using a winforms timer (I think). With websites all instances of variables and classes are destroyed when the page is send to the browser (garbage collection). So LogoutTimer only exists for a very short time. You need to use the Timer control.
https://msdn.microsoft.com/en-us/library/bb386404.aspx
You should know this also when working with websites, the Page Life Cycle:
https://msdn.microsoft.com/en-us/library/ms178472.aspx

Related

Web Api or Web Service [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I read lots of about Web Api. For example i understand Web Service is a kind of Web Api or Web Api is more flexible.
But i didn't get that: Is Web Api future of Web Service?
For example one of our client needs data from our main database. Normally i use a Web Service for this -simple- purpose but this time i created a Web Api project. I got and service data plus i figured out how it works with Entity or Identity etc. But it's not simple as a web service. I think our client will think same thing also because of identity thing. So why should i prefer Web Api vs Web Service or should i prefer Web Api in this -simple- case?
This kind of depends what you mean by 'web service', but for now I'm going to assume you mean the old .net SOAP services.
If you are building something new today (September 2015) you are almost certainly better off using an asp.net web API. This is a standard REST-style service which can be called by almost any HTTP enabled client with no requirements for local software or understanding of how the service works, this is the whole point of the REST architectural style. I blogged a little about web API and REST here: http://blogs.msdn.com/b/martinkearn/archive/2015/01/05/introduction-to-rest-and-net-web-api.aspx
In your case of a simple service that adds CRUD operations to a database using entity framework. This can be very easily achieved with Web API. You can actually scaffold this whole thing based on a simple model.
To answer your specific question, Yes I believe that in eth asp.net world at least, web API is the future of web services. In fact web services have now been dropped in favour of web API.
Web API supports the .net identity model (I blogged on this here: http://blogs.msdn.com/b/martinkearn/archive/2015/03/25/securing-and-working-securely-with-web-api.aspx) and entity framework.
Hope this helps, if it does please mark as an answer or let me know of any more details you need.
public class Service1 : System.Web.Services.WebService
{
private List<string> GetLines(string filename) {
List<string> lines = new List<string>();
//filename: ime fajla (valute.txt) SA EXT
using (StreamReader sr = new StreamReader(Server.MapPath("podaci/" + filename))) {
string line;
while ((line = sr.ReadLine()) != null) {
lines.Add(line);
}
}
return lines;
}
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public double ProcitajKursNaDan(DateTime datum, string valuta) {
List<string> podaci = GetLines("valute.txt");
double kurs = 0.0;
// Pronalazenje upisa
for (int i = 0; i < podaci.Count; i++) {
string[] linija = podaci[i].Split('|');
/* Датум[0] | Oznaka valute[1] | Kurs[2] */
string dat = linija[0];
string val = linija[1];
string vrednost = linija[2];
// Uklanjanje viska
dat = dat.Trim();
val = val.Trim();
vrednost = vrednost.Trim();
// Konverzija:
DateTime datIzFajla = DateTime.ParseExact(dat, "d/M/yyyy", null);
double kursIzFajla = Convert.ToDouble(vrednost);
if (DateTime.Compare(datIzFajla, datum) == 0 && val == valuta)
kurs = kursIzFajla;
}
return kurs;
}
[WebMethod]
public bool UpisiKursNaDan(DateTime datum, string valuta, double Kurs) {
string date = datum.ToString("d/M/yyyy");
string linijaZaUpis = date + " | " + valuta + " | " + Kurs.ToString();
bool success = false;
try
{
StreamWriter sw = new StreamWriter(Server.MapPath("podaci/valute.txt"), true);
sw.WriteLine(linijaZaUpis);
sw.Close();
success = true;
}
catch {
success = false;
}
return success;
}
[WebMethod]
public List<string> ProcitajSveValute() {
List<string> linije = GetLines("valute.txt");
List<string> ValuteIzFajla = new List<string>();
for (int i = 0; i < linije.Count; i++) {
string linija = linije[i];
string valuta = linija.Split('|')[1];
valuta = valuta.Trim();
ValuteIzFajla.Add(valuta);
}
List<string> ValuteKraj = ValuteIzFajla.Distinct().ToList();
return ValuteKraj;
}
}
}
//using A10App.localhost;
//namespace A10App
//{
// public partial class pregledkursa : System.Web.UI.Page
// {
// protected void Page_Load(object sender, EventArgs e)
// {
// if (!this.IsPostBack) {
// Service1 servis = new Service1();
// List<string> valute = servis.ProcitajSveValute().ToList();
// for (int i = 0; i < valute.Count; i++)
// DropDownList1.Items.Add(valute[i]);
// }
// }
// protected void Button1_Click(object sender, EventArgs e)
// {
// string datum = TextBox1.Text;
// string valuta = DropDownList1.Text;
// Service1 servis = new Service1();
// double kurs = servis.ProcitajKursNaDan(DateTime.ParseExact(datum, "d/M/yyyy", null), valuta);
// if (kurs != 0.0)
// Label2.Text = kurs.ToString();
// else
// Label2.Text = "Nije pronadjen kurs";
// }
// }
//}
//namespace A10App
//{
// public partial class azuriranjeliste : System.Web.UI.Page
// {
// protected void Page_Load(object sender, EventArgs e)
// {
// if (!this.IsPostBack)
// {
// Service1 servis = new Service1();
// List<string> valute = servis.ProcitajSveValute().ToList();
// for (int i = 0; i < valute.Count; i++)
// DropDownList1.Items.Add(valute[i]);
// }
// }
// protected void Button1_Click(object sender, EventArgs e)
// {
// string datum = TextBox1.Text;
// string valuta = DropDownList1.Text;
// string kurs = TextBox2.Text;
// Service1 servis = new Service1();
// servis.UpisiKursNaDan(DateTime.ParseExact(datum, "d/M/yyyy", null), valuta, Convert.ToDouble(kurs));
// }
// }
//}

ASP.Net and Parallel.Foreach causes buttons to stop working?

i have a very large database of images from the web which i am categorizing (downloaded locally).
so i have a website (locally) to do this, but the db queries were taking long, so i got an idea to "preload" the next page, so that only the very first load of the page would be slow. I save the list of items loaded in a seperate thread in session. So far so good.
I wanted to optimize further, and did some testing on what took the longest, and loading the images to check the size to see if i needed to scale them (set image height and width on the img obj) - so i wanted to do this with a parallel.foreach loop - but after doing this, my buttons on the page stopped responding? i can see the page runs through the page_load event when i press a button, but it doesn't reach the buttons "code":
protected virtual void btnSaveFollowPosts_Click(object sender, EventArgs e)
{...}
any take on what i am doing wrong? i have tried to limit the degree of paralellelism to 1 just to see if that would fix it - but it did not.
Update - code:
trying to boil it down:
protected void Page_Load(object sender, EventArgs e)
{
Search(false);
}
protected void Search(bool updateCounters)
{
if (Session[SessionItems] == null)
{
if (Session[SessionItemsCache] == null)
{
//if is being constructed, wait, else construct
//if construction is not running
if (Session[SessionCacheConstructionRunning] == null)
{
StartPreLoadContent();
}
while (Session[SessionCacheConstructionRunning] != null)
{
Thread.Sleep(25); //block main thread untill items ready
}
}
List<ContentView> contentViewList = Session[SessionItemsCache] as List<ContentView>;
Session[SessionItemsCache] = null; //clean preload cache
Session[SessionItems] = contentViewList; //save in current usage storage
Filltable(ref tblContent, contentViewList);
//preload next batch
StartPreLoadContent();
}
else
{
List<ContentView> contentViewList = Session[SessionItems] as List<ContentView>; //get items from session
Session[SessionItems] = contentViewList; //save in current usage storage
Filltable(ref tblContent, contentViewList);
}
}
protected void StartPreLoadContent()
{
Session[SessionCacheConstructionRunning] = true;
//start task
Thread obj = new Thread(new ThreadStart(RunPreLoadContent));
obj.IsBackground = true;
obj.Start();
}
protected void RunPreLoadContent()
{
using (DBEntities entities = new DBEntities())
{
entities.CommandTimeout = 86400;
IQueryable<ContentView> query = entities.ContentView.Where(some criterias);
List<ContentView> contentViewListCache = query.ToList();
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 7;
Parallel.ForEach(contentViewListCache, options, content =>
{
try
{
Interlocked.Increment(ref imageSizeCount);
string path = Path.Combine(basePath, content.LocalPath);
int imageSize = 150;
using (System.Drawing.Image realImage = System.Drawing.Image.FromFile(path))
{
double scale = 0;
if (realImage.Height > realImage.Width)
{
scale = (double)realImage.Height / imageSize;
}
else
{
scale = (double)realImage.Width / imageSize;
}
if (scale > 1)
{
content.ImageHeight = (int)((double)realImage.Height / scale);
content.ImageWidth = (int)((double)realImage.Width / scale);
content.ImageScaled = true;
}
content.ShowImage = true;
}
}
catch (Exception)
{
}
});
Session[SessionItemsCache] = contentViewListCache;
Session[SessionCacheConstructionRunning] = null; //cache ready
}
protected virtual void btnSave_Click(object sender, EventArgs e)
{
try
{
//save
...some reading and saving going on here...
//update
Session[SessionItems] = null;
Search(true);
}
catch (Exception error)
{
ShowError(error);
}
}
I agree with a previous comment: you should probably do this logic earlier in the page lifecycle. Consider overriding OnInit and putting it there.
Also, you could try this line of code instead of your current thread code (which is more suited to Windows not Web programming):
using System.Threading.Tasks;
Task.Run(() => { RunPreLoadContent(); });

SharePoint Web Part Custom Properties Don't Take Effect Until Page Reload

I am developing a sharepoint 2007 web part that uses custom properties. Here is one:
[Personalizable(PersonalizationScope.User), WebDisplayName("Policy Update List Name")]
[WebDescription("The name of the SharePoint List that records all the policy updates.\n Default value is Policy Updates Record.")]
public string PolicyUpdateLogName
{
get { return _PolicyUpdateLogName == null ? "Policy Updates Record" : _PolicyUpdateLogName; }
set { _PolicyUpdateLogName = value; }
}
The properties work fine except that the changes are not reflected in the web part until you leave the page and navigate back (or just click on the home page link). Simply refreshing the page doesn't work, which makes me think it has something to do with PostBacks.
My current theory is that the ViewState is not loading postback data early enough for the changes to take effect. At the very least, the ViewState is involved somehow with the issue.
Thanks,
Michael
Here is more relevant code:
protected override void CreateChildControls()
{
InitGlobalVariables();
FetchPolicyUpdateLog_SPList();
// This function returns true if the settings are formatted correctly
if (CheckWebPartSettingsIntegrity())
{
InitListBoxControls();
InitLayoutTable();
this.Controls.Add(layoutTable);
LoadPoliciesListBox();
}
base.CreateChildControls();
}
...
protected void InitGlobalVariables()
{
this.Title = "Employee Activity Tracker for " + PolicyUpdateLogName;
policyColumnHeader = new Literal();
confirmedColumnHeader = new Literal();
pendingColumnHeader = new Literal();
employeesForPolicy = new List<SPUser>();
confirmedEmployees = new List<SPUser>();
pendingEmployees = new List<SPUser>();
}
...
// uses the PolicyUpdateLogName custom property to load that List from Sharepoint
private void FetchPolicyUpdateLog_SPList()
{
site = new SPSite(siteURL);
policyUpdateLog_SPList = site.OpenWeb().GetList("/Lists/" + PolicyUpdateLogName);
}
...
protected void InitListBoxControls()
{
// Init ListBoxes
policies_ListBox = new ListBox(); // This box stores the policies from the List we loaded from SharePoint
confirmedEmployees_ListBox = new ListBox();
pendingEmployees_ListBox = new ListBox();
// Postback & ViewState
policies_ListBox.AutoPostBack = true;
policies_ListBox.SelectedIndexChanged += new EventHandler(OnSelectedPolicyChanged);
confirmedEmployees_ListBox.EnableViewState = false;
pendingEmployees_ListBox.EnableViewState = false;
}
...
private void LoadPoliciesListBox()
{
foreach (SPListItem policyUpdate in policyUpdateLog_SPList.Items)
{
// Checking for duplicates before adding.
bool itemExists = false;
foreach (ListItem item in policies_ListBox.Items)
if (item.Text.Equals(policyUpdate.Title))
{
itemExists = true;
break;
}
if (!itemExists)
policies_ListBox.Items.Add(new ListItem(policyUpdate.Title));
}
}
Do some reading up on the Sharepoint web part life cycle. Properties are not updated until the OnPreRender event.

Count the no of Visitors

I have stored resumes in my database and i have retrive it from asp.net web page by creating linkbutton...i can view ,download the resumes which i stored in my database.My issuse is when i view one resume example (domnic resume)then no of visitor for domnic resume should be count .if again i view that resume no of visitor should be 2...how can i do that in asp.net?
There are a ton of ways to do this, each have their quirks. Here is a quick and dirty way to do it, the only thing to remember is that the Session_OnEnd can be a bit flaky.
public void Application_OnStart(Object sender, EventArgs e)
{
Hashtable ht = (Hashtable)Application["SESSION_LIST"];
if(ht == null)
{
ht = new Hashtable();
lock(Application)
{
Application["SESSION_LIST"] = ht;
Application["TOTAL_SESSIONS"] = 0;
}
}
}
public void Session_OnStart(Object sender, EventArgs e)
{
Hashtable ht = (Hashtable)Application["SESSION_LIST"];
if(ht.ContainsKey(Session.SessionID) == false)
{
ht.Add(Session.SessionID, Session);
}
lock(Application)
{
int i = (int)Application["TOTAL_SESSIONS"];
i++;
Application["TOTAL_SESSIONS"] = i;
}
}
public void Session_OnEnd(Object sender, EventArgs e)
{
Session.Clear();
Hashtable ht = (Hashtable)Application["SESSION_LIST"];
ht.Remove(Session.SessionID);
lock(Application)
{
int i = (int)Application["TOTAL_SESSIONS"];
i--;
Application["TOTAL_SESSIONS"] = i;
}
}
Here's another way...
Membership.GetNumberOfUsersOnline();
You can keep track of no of views displayed by keeping the count in the database or a persistent storage of your choice. Whenever a particular resume view is requested, update the view count for that resume. You may disclose some elements of the design you have done to get more specific answers.
If you just want to see this count as a developer/admin, and you have interest in collecting stats site-wide, you may also look into using Google Analytics.

Page generation time - ASP.Net MVC

I'm looking for a way to track how long it took for a page to be generated by the server. I know I can use Trace to track this but I need a way to display this per page.
Its ASP.Net MVC 2
You can implement it like a ActionFilterAttribute
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class LoggingAttribute : ActionFilterAttribute
{
private readonly Stopwatch _sw;
public LoggingAttribute()
{
_sw = new Stopwatch();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_sw.Start();
Debug.WriteLine("Beginning executing: " + GetControllerAndActionName(filterContext.ActionDescriptor));
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
_sw.Stop();
var ms = _sw.ElapsedMilliseconds;
Debug.WriteLine("Finishing executing: " + GetControllerAndActionName(filterContext.ActionDescriptor));
Debug.WriteLine("Time elapsed: "+ TimeSpan.FromMilliseconds(ms).TotalSeconds);
}
private string GetControllerAndActionName(ActionDescriptor actionDescriptor)
{
return actionDescriptor.ControllerDescriptor.ControllerName + " - " + actionDescriptor.ActionName;
}
}
Decorate every controller or action-method with it and voila, it spit outs the text in debug.
EDIT: If you want to print it on the page you could add this snippet to the OnActionExecuted method
if(filterContext.Result is ViewResult) { //Make sure the request is a ViewResult, ie. a page
((ViewResult) filterContext.Result).ViewData["ExecutionTime"] = ms; //Set the viewdata dictionary
}
Now you have the executiontime saved in ViewData and can access it in the page.. I usually put it in the masterpage like this
<!-- The page took <%= ViewData["ExecutionTime"] %> ms to execute -->
Yep the Derin Suggestion is the standard Way to do it in an ASP.NEt application, i would just suggest add an if so it does not interfere with non-HTML responses:
EDIT: added complete implementation
public class PerformanceMonitorModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += delegate(object sender, EventArgs e)
{
//Set Page Timer Star
HttpContext requestContext = ((HttpApplication)sender).Context;
Stopwatch timer = new Stopwatch();
requestContext.Items["Timer"] = timer;
timer.Start();
};
context.PostRequestHandlerExecute += delegate(object sender, EventArgs e)
{
HttpContext httpContext = ((HttpApplication)sender).Context;
HttpResponse response = httpContext.Response;
Stopwatch timer = (Stopwatch)httpContext.Items["Timer"];
timer.Stop();
// Don't interfere with non-HTML responses
if (response.ContentType == "text/html")
{
double seconds = (double)timer.ElapsedTicks / Stopwatch.Frequency;
string result_time = string.Format("{0:F4} sec ", seconds);
RenderQueriesToResponse(response,result_time);
}
};
}
void RenderQueriesToResponse(HttpResponse response, string result_time)
{
response.Write("<div style=\"margin: 5px; background-color: #FFFF00\"");
response.Write(string.Format("<b>Page Generated in "+ result_time));
response.Write("</div>");
}
public void Dispose() { /* Not needed */ }
}
you can also add some style to it...
And remember to register your Module in WebConfig inside httpModules Section:
<add name="Name" type="namespace, dll"/>
For a Complete Reference about this check the Pro ASP.NET MVC Framework by Steven Sanderson - Chapter 15 - Performance, Monitoring Page Generation Times.
EDIT:(comment #Pino)
Here is the example for my project:
alt text http://www.diarioplus.com/files/pictures/example_performance.JPG
It will depend on where you want to include this information. For example you could write an http handler that will display the render time after the </html> tag:
public class RenderTimeModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, e) =>
{
var watch = new Stopwatch();
var app = (HttpApplication)sender;
app.Context.Items["Stopwatch"] = watch;
watch.Start();
};
context.EndRequest += (sender, e) =>
{
var app = (HttpApplication)sender;
var watch = (Stopwatch)app.Context.Items["Stopwatch"];
watch.Stop();
var ts = watch.Elapsed;
string elapsedTime = String.Format("{0} ms", ts.TotalMilliseconds);
app.Context.Response.Write(elapsedTime);
};
}
public void Dispose()
{
}
}
If you want to display render time somewhere in the middle of the html page then this render time will not account for the total page render time.

Resources