how to display something one time every hour in asp.net ?
example for show messeage in Begining hour one time only?
i use for asp.net ajax timer control?
protected void Timer1_Tick(object sender, EventArgs e)
{
MessageBoxShow(Session["playsound"].ToString());
Session["playsound"] = 1;
}
but alway null?
---------------------------
Message from webpage
---------------------------
Object reference not set to an instance of an object.
---------------------------
OK
---------------------------
Sounds like your session might have timed out. If, between AJAX calls, your session expires on the server, then the ToString invocation may be operating on a null reference:
MessageBoxShow(Session["playsound"].ToString());
This would appear to coincide with what the AJAX client script is attempting to tell you.
This could also be the result of Session["playsound"]; being uninitialised.
The default session expiry duration for ASP.NET is 20 minutes, which you should be mindful of if you're executing an hour long timer.
You can use the
window.setInterval
method
It calls a function repeatedly, with a fixed time delay between each call to that function.
intervalID = window.setInterval(func, delay[, param1, param2, ...]);
Read more info
window.setInterval
On the client?
The only way I know to do this is via a javascript timer.
One way of doing this could be to have an session variable with NextTime to show the item on the page. If its null one could display the item now (or get the NextTime scheduled). On every page refresh, if the current time is after the Next Time, show the item and reset the NextTime session variable to the next Hour.
This would only work if the user is navigating the site and the page is being refreshed.
You can use the javascript variable window.name which keeps its value between page refreshes.
You could store a 'last checked time' in there and compare it with the current time.
If the user navigates to another site and that site clears this variable then your back to square one.
An easy answer would be to use a small cookie to store the original time and then query it every so often (~5 min?) this way the session won't run out and you're not SOL if the user leaves the page (if that's what you want).
DISCLAIMER: I haven't really dipped my toes into AJAX yet even though I've been programming ASP.net all summer, so excuse me if this isn't possible.
Related
There are multiple ways to leverage ASP.Net MVC response/output caching. At the simplest you can cache a simple page that's the same for everyone:
[OutputCache(Duration=24*3600)] // cache 1 day
public ViewResult Index() ...
You can vary by specific params, you can bust the cache by a custom key. In all of those cases, the declarative OutputCacheAttribute is used to determine whether the page should just serve from cache. If it does serve from cache, the Action doesn't fire - CPU time saved.
So, suppose the Action accepts an Id, meaning its contents vary id to id. Suppose you want to bust the cache for specific Ids when their underlying data changes. MSDN says to set VaryByCustom inside the Action instead of declaratively in OutputCacheAttribute:
Response.Cache.SetVaryByCustom
Like:
[OutputCache(Duration=24*3600, VaryByParam="id")]
public async Task<ViewResult> Thing(string id)
{
Response.Cache.SetVaryByCustom("thing-" + id);
// Some big load of work we'd like to avoid when a ton of visitors hit
// the server goes here.
So... in every scenario until this one, that big load of work in the Action gets skipped if the page is valid in the cache. But it appears here it's not - unless SetVaryByCustom can interrupt the Action? How does this command work exactly?
If it doesn't interrupt the Action, is there some follow-on check I can do to see if the cache picked it up, so I can return early? And what would I return, given it's normally expecting a whole page filled with data?
Based on testing, it appears to work neither of the ways I proposed.
In my Action with this strategy applied, I:
Fire a log event
Fire SetVaryByCustom(id);
Fire another log event
And here's what I saw:
BrowserA: Visit a given id
Log: Both events fire - before and after
BrowserB: Visit same id
Log: (nothing)
BrowserA: Change id so an Invalidate fires for id
BrowserB: Visit id, sees 200
Log: Both events fire - before and after
BrowserA: Visit id, sees 200
Log: (nothing)
BrowserB: Visit id, sees 304
Log: (nothing)
In other words, the entire Action doesn't fire, just like in the static/declarative approach where it's all done in OutputCacheAttribute. What's pretty strange is each time it invalidates, the key gets an opportunity to change - you could pass a new key to SetVaryByCustom once per invalidation, but not more.
Unless you explicitly tell ASP.Net not to, the browser is also told to cache these pages, for the length of time remaining in the 24-hr period (via max-age). That means depending on how your visitors arrive, they may not see the page change as you intended. You can prevent this of course with Location=OutputCacheLocation.Server in your OutputCacheAttribute.
In any case, my core objective is in fact met - the server skips the CPU cost of the Action - just a bit more than I anticipated.
I have a system set up to lock certain content in a database table so only one user can edit that content at a time. Easy enough and that part is working fine. But now I'm at a road block of how to send a request to "unlock" the content. I have the stored procedure to unlock the content, but how/where would I call it when the user just closes their browser?
You also can't know when the user turns off his computer. You have to do it the other way around.
Require that the lock be renewed periodically. Only the web site would do the periodic renewal. If the user stops using the web site, then the lock expires.
Otherwise, require the user to explicitly unlock the content. Other users who want to edit the content can then go yell at the first user when they can't do their jobs. Not a technological solution, but still a good one. Shame works.
The best thing you can really do is add something to your Session_End in your global.asax. Unfortunately, this won't fire until the session times out.
When the user clicks the "X" in their browser, there isn't anyway to guarantee the browser will send you anything back.
A quick note on the Session_End approaches. If you use this method, then you have to ensure
That sessionstate is InProc, eg. add something like this to your Web.config
<sessionState mode="InProc" timeout="timeout_in_minutes"/>
Make sure that you've setup IIS as to not recycle worker processes during normal operation (see for instance this blog post).
Edit:
Not directly answering the question directly, but another approach would be to use Optimistic concurrency control on the data in question.
There is such event as "user closes browser".
Nevertheless, I can think of two workarounds:
Use Javascript/Ajax to permanently
(lets say every 10 seconds) call a
method in your page. The DateTime of
your last query needs to be stored
somewhere. Now you write a windows
service that checks every second
which session are timed out. Perform
your custom action there.
Use the global.asax Session_End()
-Event. (cannot be used with every SessionState, look up for which ones
it is usable)
Trying to leave a stackoverflow answer page pops up an "are you sure" dialog. Perhaps during the on-page-leave event that SO uses (or however SO does this), you can send a final request with an XmlHttpRequest object. This won't cover if the browser process closes unexpectedly (use session_onend for that), but it will at least send the "I'm closed" event earlier
I think your one stored procedure can do the locking and unlocking (used with "Select #strNewMax As NewMax")...
Here is an example from a system I have:
Declare #strNewMax Char
Select #strNewMax = 'N'
BEGIN TRANSACTION
/* Lock only the rows for this Item ID, and hold those locks throughout the transaction. */
If #BidAmount > (Select Max(AB_Bid_AMT) from AuctionBid With(updlock, holdlock) Where AB_AI_ID = #AuctionItemId)
Begin
Insert Into AuctionBid (AB_AI_ID, AB_Bid_AMT, AB_Emp_ID, AB_Entry_DTM)
Select #AuctionItemId, #BidAmount, #EmployeeId, GetDate()
Select #strNewMax = 'Y'
End
COMMIT TRANSACTION
Select #strNewMax As NewMax
This will insert a record as the next highest bid, all while locking the entire table, so no other bids are processed at the same time. It will return either a 'Y' or 'N' depending on if it worked or not.
Maybe you can take this and adjust it to fit your application.
I have this code in the asp.net application start evert, and I'm not really familar with the Timer class but what I want to do is have one Trigger that goes off every night at 11 pm, one that goes off at 5:30 in the morning and then every hour after that.
private System.Threading.Timer timer;
protected void Application_Start(object sender, EventArgs e)
{
int intervalMilliseconds = 60 * 1000;
timer = new System.Threading.Timer(new System.Threading.TimerCallback(TimedEvent), null, intervalMilliseconds, intervalMilliseconds);
}
protected void Application_End(object sender, EventArgs e)
{
if (timer != null) timer.Dispose();
}
private void TimedEvent(object stateInfo)
{
MyClass.ExecuteCode();
}
*Please no answers in the way of "don't use asp.net to do triggers because of the lifecycle".
*Again - please no posts on what not to use. I've received two post both telling me what not to use and both not related to my question which is about the Timer class and how to use it.
From your question i'm assuming you don't have full control over your hosting environment, so will try to avoid the schedule it... etc answers.
Having said that, you still need to be aware of the asp.net lifecycle, and your trigger approach is fraught with dangers.
Do you get enough traffic that the application won't end unexpectedly? Do you know the configuration of IIS, so recycling is not a worry?
I can see three approaches:
I would recommend having a page, which uses some sort of key, which is only known
by the caller. Have this page triggered by a watchmouse (See: http://www.watchmouse.com/en/), or scheduled crawler on a pc/server which will always be on, at the times you need it to be triggered.
An alternative would be to trigger a database process, which runs when needed to.
Depending on your environment, this can be scheduled too.
Another would be to check a log file, on users accessing the page, and if it is the first access within the hour, trigger your process. (Do this for whatever period you need.)
However this depends entirely on how heavily your site is accessed, and may not work reliably.
When you create your timer and hook up its tick/elapsed event, set the interval to be every 5 minutes or so.
Then in the tick/elapsed event handler, check the current time and perform an action where necessary. Obviously you will also need to record when an actino has been performed so you don't perform it at 10:58 and 11:03 pm.
Have a look at Quartz.NET, which will allow you to set up cron-like triggers.
Maybe a different way of doing what you want: Instead of relying on ASP to be active, perhaps you can just use the windows scheduler to schedule your event. It has more of the scheduling features you want and will be likely be more reliable as well as already debugged. Your timed event can be as simple as accessing http://localhost/YourApp/.aspx. You'll get the same effect with the added benefit that if your app happens to have recycled, your event will still execute as the 1st request.
You can do the kind of thing you're describing by using the inbuilt ASP.NET Cache.Add CacheItemRemovedCallback delegate. It's a bit of a roundabout way of using it, but you can do effective scheduling this way.
There's an article here showing how to do it.
More information on the CacheItemRemovedCallback here.
Edit: I know you said no services, but if you check the server and find you can use Scheduled Tasks, you can use that to run a console app on a specific schedule like some other other answers mention.
I'm currently developing an ASP.NET application which uses a MasterPage and I want to measure my application webform's loading time and display that information to the client.
My current strategy involves using the Application_BeginRequest event associated callback (in the Global.asax file of my website solution), to start the measurement of the time spent on the server-side process (as follows)
protected void Application_BeginRequest(Object sender, EventArgs e) {
Context.Items.Add("Request_Start_Time", DateTime.Now);
}
and calculate the elapsed time on the webform's OnPreRender event associated callback, printing it on a placeholder element (as follows)
protected override void OnPreRender(EventArgs e) {
base.OnPreRender(e);
TimeSpan tsDuration = DateTime.Now.Subtract((DateTime)Context.Items["Request_Start_Time"]);
ExecutionTime.InnerHtml = "<em>Server-side processing duration: " + tsDuration.TotalMilliseconds + " miliseconds.</em>";
}
is this the best way to measure loading time? Is there a more "elegant" way to accomplish this?
Thanks in advance for your time and cooperation.
<%# Page Trace="true" %> (or set this in web.config)
Enable tracing and check out the information in trace.axd (in the root of your website).
Then you could set timing points with:
Trace.Write("Start time intensive task");
Trace.Write("Stop time intensive task");
http://msdn.microsoft.com/en-us/library/bb386420.aspx
This is assuming "your client" want deep debug data.
Your appproach seems to be exact enough, as long as you do not render very large control trees and you don't use server controls that do all their work in an overridden Render method (unexperienced server control authors tend to do exactly that...).
In that case, there is actually a way to render the actual rendering time ;-) Just use a HttpResponse.Filter object to fill a placeholder with the elapsed time. These filters are applied after the web form is rendered and before it goes to the client.
If you need this just for development, search for trace.axd, this will give you a lot of details not only about timing but also the request context, control tree structure and page size.
This really depends on what metric you are looking to actually show.
Is this an overall "page loaded in __ seconds" type thing that will be there all the time?
Is this to determine if your coded solution meets requirements for a client, and not needed for production?
The answer to these two will dictate what makes the most sense when it comes to recording. If your goal is #1, then I would say your method works. If you are going for number 2, I could be looking at what Erwin has.
We are following a procedure in our work while developing a web page, is to bind page to one or more session variables, these session variables are used only for that page, to hold current processing objects, so while closing page no need for them.
How could I discard these session variables while closing page?
Any suggestions regarding that technique or how to solve that problem?
There is no server-side event that is raised when a page is left/closed. Also the Session_End event (mentioned in other answers) is not called when a page is left, since the user might navigate to other pages of the same web application (and therefore the session will continue to exist).
I can think of 3 possible ways to solve (or work around) this issue:
1 - use ViewState to store data with page-scope. This is what ViewState is made for, and unless you have a lot of data, it should not be a problem. If you have a lot of data, remember, that it will be serialized/deserialized and sent to the client/back to the server for every request (which may result in large requests and therefore bad performance).
2 - instead of putting the data into the session, put it into the Cache (with a low sliding expiration timeout). On your page, you can access your data in the same way as from the session, i.e. data = Cache["data"], but you have to be prepared that the data was removed from the Cache (you have to re-load it again from DB for example), if the time between two requests was bigger than the expiration time.
3 - use the client-side (javascript) onUnload event, and trigger some action (e.g. a ajax callback) to remove the data from the session. But I think the onUnload event is not reliable (it will not be fired in any case, e.g. when the browser is terminated by a crash or with the task manager, or if javascript is disabled).
If you use variables for only that page, store them in viewstate. ViewState is suitable for page scoped variables.
If you are using ASP.NET sessions (which you probably are), you can add a global.asax file to your soluting. In there this event-delegate is to be found (if not, create it):
protected void Session_End(object sender, EventArgs e)
{
}
.. In here you can clear your session collection.
protected void Session_End(object sender, EventArgs e)
{
Session.Clear();
}
This will be fired when the session expires or when a user clicks logout :)