Fire a server side method on aspx page immediately after an interrupt - c#

Imagine that I have an aspx page that is home page of my site and users spend their times at it. Now I need after occurring an occurrence, this page become update. For example if a new user joined to website all users see it on their home page.
I use a ajax timer for solving my problem and one method is called every one second and if my site has been changed, I can show it to users. But this is no good solution. Please tell me how I can fire a method immediately after an interrupt like above example.
(I think yahoo mail use this way too when we get some new emails)
Thanks for any help.

you can make the current thread 'sleep' entil new changes comes up. Each web request correspont to a thread. and you need to use a global collection to keep track of all currenlt sleeping thread.
var lastMsgTime=Global.NewMsgTime;
while(true){
Thread.Sleep(300);
if(!Response.IsClientConnected||RequeGlobal.NewMsgTime!=lastMsgTime){
lastMsgTime!=Global.NewMsgTime;
break;
}
}
you'll still be using ajax on client side.

Related

Invoke code-behind method when browser is closing

I need to find a way to intercept browser closing and invoke a metod to update a record with several information about logged user in DB. It's very important this record is updated when the user is logging-out or when he close the browser. Obviously when the user clicks 'Logout' I handle the update in the server-side event, but what if the user simply exit from browser?
Someone suggest to use the window.onbeforeunload event and make an asynchronous call to some WS or WebMethod to execute the code, but this doesn't convince me at all: the problem with onbeforeunload is that it shows a confirm prompt. I need to avoid this message and simply invoke the method.
So I'm wondering if there is a 'server-side' solution without using ajax or javascript.
For example... a way to trigger some event on session abandon or session clear, or some other way to solve this problem just working on code-behind...
There is no way you could have a server-side solution to know something that happens in the client browser.
I do not believe there is any way to do what you need server-side only. Client side is the only way. Server has no way of knowing when browser window was closed, this is limitation of HTTP protocol.
Yes, you can put an event in the Global.AsaX which will fire when the session ends. Now if you need data from the client to update the db etc., you'll need a way of getting it there, but if not, then the Session_End will do the trick.
Note: Session end is slightly different than the browser closing, so it this will depend on what you want the event firing to do.
How to handle session end in global.asax?
I'd like to find a 'server-side' solution without using ajax or
javascript.
I suspect that it's impossible with that requirement.
Maybe you could do something like:
Have a hidden IFRAME on the page
Set the Refresh header on this IFRAME (or use a META element) to contact the server every couple of seconds
If you do not hear from the client for some period of time, assume the browser has been closed.
However, I imagine that this solution will not scale well.
Have you considered something like signalr? I use it to detect when someone has a record open.
public class ChatHub : Hub
{
public override Task OnDisconnected()
{
Broadcaster.Disconnected(Context.ConnectionId);
return base.OnDisconnected();
}
}
For the moment I changed radically the approach to my problem.
To update pending rows I implemented a timed job using Quartz.NET framework, that runs every night.

subscribing takes too long for users to wait on webpage for confirmation... solutions?

On our .NET 3.5 website in c# a user clicks submit on our webpage, they are subscribed by email address to our reports. Unfortunately, this action takes about 5 minutes and the user has to sit and wait for confirmation. What I would like to do is change it so that when they click submit, they get a pop up that says they will be notified by email when their subscription goes through, meanwhile i would queue up the subscribe action somewhere else on the server so that it doesnt exist in the web code. Can you give me some ways to do this? The basic idea is that I want to split into two different lines of execution where one will allow them to still browse our website and the other will subscribe them. I was thinking split into a new thread but I think that the web code would still have to wait for that thread to finish before they could do anything else. I'm looking for ideas, preferably something that can run on the same server. thanks!
There's many options, but the basic approach will be to decouple the site from the provider. Instead you'll write out a record saying "User X is waiting to subscribe", a seperate process will then read the record and perform the actual subscription, while marking the record as "in-progress". Once the process has complete the record will again be updated with the completed information.
You can achieve this with databases, message queues, or other approaches. But fundamentally your site will only be responsible for creating the record and checking it's status--the actual interaction with the provider will be handled separately.
If you have something that takes this long and you want to true and ensure the action goes through, then your best bet is going to be to queue it up.
Basically, when they submit the request, store that in a database table and let them move on. Meanwhile, have another process that monitors that table to process the requests. When they come in just have this second process send the request on to the part that takes 5 minutes to complete.
Once it finishes, send them a "welcome to such and such email list" message. That will serve as their confirmation that it worked.
Jeff Atwood blogged on a relevant topic here a while back. Since you are using c#, I assume you're using ASP.NET and can take advantage of the cache mechanisms to kick off a periodic worker job. On the user's request, you can persist details of the subscription to some data store. In that job, you can examine the queue to determine what subscriptions need to be created and then execute them.
https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

How to set server controls value from thread in C# web application?

I have a long running thread in my web page on a button click event
var thread = new Thread(StartTaskMonitoring);
thread.Start();
In method 'StartTaskMonitoring' I am running a while loop which depends on boolean variable _StopMonitoring
Another button "Stop" which resets the _StopMonitoring variable which makes start button event stop.
But the problem is that when I am executing thread, I am unable to update UI – say I want to update a textbox in StartTaskMonitoring method. Or it could be a progress bar.
Already tested Updatpanel1.Update(). It doesn't help. Also cannot get sessions from the thread.
How do I achieve this? so that ui is updated.
In a web application, once the request has been completed by the server (all the data sent to the client) the server cannot change anything without some action from the client.
Code on the server has no mechanism to send additional data to the client which will change the display, the only mechanism is for the client to send a request to the server1. The client can sent requests (on a timer or in response to a user action) for data and then process the new information to update the UI (this is "AJAX").
1 In the future Web Sockets will provide an easier approach, but that still requires code on the client to process the messages from the server.
The thing with background threads is that they may run even after the HTTP request has ended and rendered the page to the user. So talking about modifying UI in threads doesn't make sense. You may checkout the following article.
If you're running a process that takes a very long time then I think that your only way forward here is to have the process run as a non-web application, preferably a service and poll it for information using AJAX calls from your web app.
You'd need to provide some control within the service in order to cope with multiple demands for processing from the same session and also what to do if the session expires before the thread has completed.

Response.Redirect("page.aspx") doesn't always work

In my application this code:
CreditsSubjectsNamesTeacherCount n = new CreditsSubjectsNamesTeacherCount();
Session["UserID"] = n.GenerateTeacherCountCrossRegions(txtStartYear.Text.CheckOnEmptyYear(), ((UserInformation)Session["UserInformation"]).UserName);
Response.Redirect("page.aspx");
doesnt redirect if the method GenerateTeacherCountCrossRegions was executing for a long time(~ >10 min). What can cause this problem?PS: added: <httpRuntime executionTimeout="18000".. > but it didnt help. Thank you.
The request has timed out. Response.Redirect sends an HTTP response asking the browser to request a different page - if the request has timed out at the browser, it won't accept this response.
The browser has stopped waiting for the page, so there is no longer a connection. The server just sends the redirect into void, where noone is listening.
Start the work in a separate thread, so that the response doesn't have to wait for it to complete. Redirect to a page that reloads occationally to check the status of the work, and redirect to the final page when the work is complete.
To communicate with the background thread you need an object that both threads has a reference to. You can store a reference to the object in a session variable so that the page checking the status has access to it.
The request will time out, so the browser will display an error rather than the expected page. Note that this will likely not happen while debugging, only on deployment.
For long running operations of this kind consider a different interface.
I've created a system where the analyzed data is sent by email to the user when it's been calculated: internally I've spawned off a BackgroundWorker thread to do the calculation that then uses a MailMessage to send the report as a PDF attachment.

Running server-side function as browser closes

Background: I'm creating a very simple chatroom-like ASP.NET page with C# Code-Behind. The current users/chat messages are displayed in Controls located within an AJAX Update Panel, and using a Timer - they pull information from a DB every few seconds.
I'm trying to find a simple way to handle setting a User's status to "Offline" when they exit their browser as opposed to hitting the "Logoff" button. The "Offline" status is currently just a 1 char (y/n) for IsOnline.
So far I have looked into window.onbeforeunload with Javascript, setting a hidden form variable with a function on this event -> Of course the trouble is, I'd still have to test this hidden form variable in my Code-Behind somewhere to do the final Server-Side DB Query, effectively setting the User offline.
I may be completely obfusticating this likely simple problem! and of course I'd appreciate any completely different alternative suggestions.
Thanks
I suspect you are barking up the wrong tree. Remember, it is possible for the user to suddenly lose their internet connection, their browser could crash, or switch off their computer using the big red switch. There will be cases where the server simply never hears from the browser again.
The best way to do this is with a "dead man's switch." Since you said that they are pulling information from the database every few seconds, use that opportunity to store (in the database) a timestamp for the last time you heard from a given client.
Every minute or so, on the server, do a query to find clients that have not polled for a couple of minutes, and set the user offline... all on the server.
Javascript cannot be reliable, because I can close my browser by abending it.
A more reliable method might be to send periodic "hi I'm still alive" messages from the browser to the server, and have the server change the status when it stops receiving these messages.
I can only agree with Joel here. There is no reliable way for you to know when the HTTP agent wants to terminate the conversation.

Categories

Resources