Showing posts with label timer. Show all posts
Showing posts with label timer. Show all posts

Wednesday, March 28, 2012

updates from another thread

Hi, I'm trying to get a label control to update with dynamic information when a timer does its tick event.

I can get it to update with information hard-coded into the tick event, but i can't seem to get any data from a global variable or other shared resource.

Here's what i have so far-

using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Threading;public partialclass _Default : System.Web.UI.Page {string temp;protected void Page_Load(object sender, EventArgs e) { }protected void Timer1_Tick(object sender, EventArgs e) { Label1.Text ="Tick at " + DateTime.Now.ToString()+"<br />";if (temp !=null) Label1.Text +="register at-"+temp; }protected void Button1_Click(object sender, EventArgs e) { Thread a =new Thread(Foo); a.Start(); }protected void Foo() {while (true) { Thread.Sleep(100); temp = DateTime.Now.Day.ToString(); } }}

(that's actually a +"<br />" at the end of the first line on the tick event)

and the markup-

<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" /> </Triggers> </asp:UpdatePanel> </div> <asp:Timer ID="Timer1" runat="server" Interval="500" OnTick="Timer1_Tick"> </asp:Timer> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> </form> </body></html>
the 'register at" text never fires. I've tried using Session and Cache variables in place of a global string but no luck.

I am not sure how it is not working when puting it in Session/Cache, would you mind posting the code?


Here's the code using session-

using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Threading;public partialclass _Default : System.Web.UI.Page {protected void Page_Load(object sender, EventArgs e) {if (!IsPostBack) Session["Store"] =null; }protected void Timer1_Tick(object sender, EventArgs e) { Label1.Text ="Tick at " + DateTime.Now.ToString()+"<br />";if (Session["Store"] !=null) Label1.Text +="register at-" + Session["Store"].ToString(); }protected void Button1_Click(object sender, EventArgs e) { Thread a =new Thread(Foo); a.Start(); }protected void Foo() {while (true) { Thread.Sleep(100); Session["Store"] = DateTime.Now.ToString(); } }}

It is not possible to access the session/request/response/cache from an different thread, also creating thread/using threadpool is not an good practise.


How should I update the label control then?

Or if using another thread is not good practice, i don't see how i'm going to be able to get the button postback to finish so i can update the label cleint side from the server during a (partial) postback


I am still not clear about your requirment, anyway here is the code snippet which will allow you to access the session from a different thread:

protected void Button1_Click(object sender, EventArgs e){ ThreadPool.QueueUserWorkItem(new WaitCallback(foo), Session);}private void foo(object state){ HttpSessionState session = (HttpSessionState)state; session["Store"] = DateTime.Now.ToString();}

Initial tests with this method provide the functionality I was after. I'll try to implament it today and let you know how it goes.


Indeed this seems to work well. I have 2 follow up questions relating to it though-

1. I went ahead and passed the session variable to other functions I use by reference...I'm guessing this is ok?

eg-

protected void Button1_Click(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(new WaitCallback(foo), Session); }private void foo(object state) { HttpSessionState session = (HttpSessionState)state; Thread.Sleep(100); session["Store"] = DateTime.Now.ToString(); Thread.Sleep(1000); foo2(ref session); }private void foo2(ref HttpSessionState session) { session["Store"] = DateTime.Now.ToString(); }

2. I notcied the application context still stays around after the browser is closed(presumably waiting for the thread to end?) should I manually be stopping the proccess somehow?


1. Yes you can pass it from the worker thread method.
2. The Thread returns to threadpool as soon as the foo2 method completes, no do not have to do anything.

Since it solved your problem, dont forget to mark it as answer.


Let's take another stab at this. You didn't really state the object of what you were trying to achieve. Why are you trying to use the variable temp? And if it truly is a shared variable, why didn't you just make it static? A Session variable certainly isn't global to the application. There's got to be a reason you're doing this and perhaps there is a much better approach.


The end result alows me to provided feekback to the cleint about a job currently being ran on the server (in psudo-real time). The timer updates the label on the client but it needs to be able to read from a variable (or somthing) that the job running on the server can write to. The session variable only needs to be global to the session (mutliple people could be using this at a time).

If there is another way to do this without using the cache or session I'd prefer too, but I havn't seen a way to do this yet...


Well there are certainly more expensive techniques such as using a Windows Service to host the job and querying it. Or using a DB entry to write the job status and querying it with a web service.

However you might be interested in this person's approach. He used a Cache object, but there is no reason it couldn't be Session (but Cache can be used if a unique identifier is set for a collection of jobs). The main difference is that his whole task is in this object, and it's public properties can be used to get it's status.

http://www.eggheadcafe.com/articles/20051223.asp


Use the Cache/ Store the Jobs status in DB as muliple user will be able to see the same result. BTW for one User you cannot use the session for storing the long running task status as the session access is always sequential.


I did try using the cache and i wasn't abe to get it to work ( see the first post). Essesntially the source looks the same as the session example except you use cache['whatever'] instead of session["whatever"].

I was under the impression that the session[] object was unique for each 'cleint session' that is, each cleint request would have it's own session object to work with. If this is the case why can't i use it for multiple users

@.wrayx1- I wanted to stay away from using a service althogh I have read some thing about how to get them to work, i think it overcompliactes the simple job I'm trying to do.

Monday, March 26, 2012

Updating gridview without postback

Hi!

I want to refresh a gridview without doing postback every second and for do it I use a System.Timer.

I have the grid into an updatepanel and I want to know how can I make, from the elapsed event of the timer, to refresh the grid.

I am trying to use theICallbackEventHandlerbut I can't reach my target.

Could anyone said me if I can do it and how could I do?

I have search code samples but they aren't useful for me.

Try this:

Put a button on the form somewhere, set the onclick event to trigger an update of the gridview. Check that pressing this button updates the gridview as expected.

Make this button invisible by using style='Display:none;'.

On the timer elapsed event add a call to myButton.Click();

Andy.


Finally I have used the Anthem.net library and its panel component. It was very easy working with it doing the refresh without the postback.

There is more information inhttp://www.codeproject.com/Ajax/AnthemNET.asp.

Updating one updatepanle data from other updatepanel

I have a september ctp atlas dll. We have one updatepanel with timer which fires every 5 seconds & get application variable data from server.In second updatepanel we have a treeview which we want to update only if value in application variable changes.If we put timer in treeview updatepanel then treeview refreshes with images,nodes which we do not want.Can we add nodes in treeview from another updatepanel.Unfortunately, the treeview is not yet supported (as well as some other databound controls that use templates)...There are some hacks you can try in the meantime...for instance the gridview when template is not supposed to be supported but I have managed to get it to work by using a combinations of controls...another good post to read is this...

Wednesday, March 21, 2012

use __doPostBack with Ajax

Hi,

I have a page that is updated frequentlly (it presents stock data) .

I use ajax contrl tool kit controls .

right now there is an ajax Timer control on the update panel, which calls the Update Panel's Update method if needed.

I get my data via wcf client proxy , my question is, is there a way to receive events from wcf on server side?

then hold an updated datatable of stock data?

Thanks

Take a look at this example ofusing __doPostBack to trigger an UpdatePanel refresh.

Additionally, you might be interested in this: http://encosia.com/2007/07/25/display-data-updates-in-real-time-with-ajax/


hello.

well, not sure on what you're asking here...if you want to have a partial refresh caused by your timer, then you should set it up as an asyncpostbacktrigger. if you only want to have a refresh when you receive new data on the server side, then you should do something like this:

1. build a web service that polls the server side to see if there is new data (you can, for instance, have a session variable that will let you know the date of the last update of the data on the server side)

2. when you receive the response you should see if you need to refresh the panel

3. if you do, you should use gt1329a's (sorry man, but i don't know your name :) ) excellent advise and force a refresh of your panel


Hi,

Thanks for your reply, I already implemented what you suggested (sorry for my confused question..)

but im looking for a more efficient solution, to reduce calls to wcf servic.(if its possible)

actually what I meant to ask is , is there a way to hold on server side a DataTable or any other data structure that

will be updated through wcf callbacks (or other type of callbacks from a DLL) , so when a client requests the page i don't need to call the wcf service.

I can bind my data presentation controls to the updated data structure , and server side will handle the updates regardless of client calls .

I think it will be more efficient then calling wcf services from the aspx pages for every request to that page and on each timer tick.

but where can I hold and update that data structure (via wcf callbacks) ?

i want it to be alive with no dependecy on page that are beeing requested.

what do you suggest?

Thanks,

tal


hello.

what you need is some sort of "asp.net singleton". adding a static field to the httpapplication object will be enough for that. here is an extremly interesting article about singletons:

http://www.yoda.arachsys.com/csharp/singleton.html

btw, do notice that this has some problems, specially when you think about web farms, etc...