I'm trying to show the console output from a process started by my webapp. I tried to set it up so that when I receive a line of text, I update the label then reload (update) the update panel, but the panel doesn't seem to update.
I can't figure out why my update panel isn't updating. I print out the console output as it is received, but the update panel doesn't update at all.
protected void RunBatch_Click(object sender, EventArgs e)
{
Process p = new Process();
p.StartInfo.FileName = #"C:\...\test.bat";
// Set UseShellExecute to false for redirection.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
// Set our event handler to asynchronously read the sort output.
p.OutputDataReceived += new DataReceivedEventHandler(OutputReceived);
// Start the process.
p.Start();
// Start the asynchronous read of the sort output stream.
p.BeginOutputReadLine();
}
protected void OutputReceived(object sender, DataReceivedEventArgs e)
{
Output_lbl.Text += e.Data;
System.Diagnostics.Debug.WriteLine(Output_lbl.Text); // I see this output
UpdatePanel1.Update(); // Doesn't update
}
.
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="Testing._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<p>
<asp:Button ID="RunBatch" runat="server" Text="Run Batch!"
onclick="RunBatch_Click" />
</p>
<asp:ScriptManager runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" >
<ContentTemplate>
<asp:Label ID="Output_lbl" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
.
EDIT:
I changed the Update Panel's UpdateMode.
I've tried to implement a timer to update the update panel, which it does, but it prints out "1:48:07 PM -- " ... and continues to count without printing any other Text even after receiving the debug messages:
This is the output from the batch file
This is the output from the batch fileThis is output line 2 from the batch file
This is the output from the batch fileThis is output line 2 from the batch fileThis is output line 3 from the batch file
.
string Text = "";
protected void OutputReceived(object sender, DataReceivedEventArgs e)
{
Text += e.Data;
System.Diagnostics.Debug.WriteLine(Text);
}
protected void Timer1_Tick(object sender, EventArgs e)
{
Output_lbl.Text = DateTime.Now.ToLongTimeString() + " -- " + Text;
}
Your panel doesn't update because you set the UpdateMode to Conditional without specifying any triggers that would cause it to postback to the server asynchronously and fetch the updated content. You would need to embed a Timer in the UpdatePanel and configure that as a trigger for the UpdatePanel. See article How to refresh update panel with a timer.
Instead of using an update panel, why don't you try using AJAX combined with a web method? UpdatePanels are notoriously difficult to work with.
Edit...
I think you're missing the idea that each request to the webserver is unique, so you need a way to persist the output from the console program between postbacks. Below, I make use of Session.
Code behind
protected void Timer1_Tick(object sender, EventArgs e)
{
Output_lbl.Text+=Session["Text"].ToString();
}
protected void OutputReceived(object sender, DataReceivedEventArgs e)
{
Session["Text"]+=e.Data;
System.Diagnostics.Debug.WriteLine(Text);
}
The ASPX page.
<asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Conditional" ChildrenAsTriggers="false">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Timer runat="server" ID="Timer1" OnTick="Timer1_Tick" Interval="150" />
<asp:Label ID="Output_lbl" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
Related
I am creating a page in ASP.NET Framework and I need to update text in Label every X seconds. I tried to create new Thread and call Thread.Sleep(), but it do not work, Everything what is written bellow Thread.Sleep do not execute, I do not know why. So I found on internet Timer. I created Timer and it do not call method. If I write it statically to .aspx it works:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" id="TimedPanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" id="DateStampLabel" />
</ContentTemplate>
</asp:UpdatePanel>
protected void UpdateTimer_Tick(object sender, EventArgs e)
{
DateStampLabel.Text = DateTime.Now.ToString();
}
This works, but I want to change time, so I created it dynamically in C#:
if (!IsPostBack)
{
Timer timer = new Timer();
timer.Tick += UpdateTimer_Tick;
timer.Interval = 2000;
timer.Enabled = true;
}
But UpdateTimer has never been called. So I tried this and it still do not work:
protected override void OnInit(EventArgs e)
{
if (!IsPostBack)
{
Timer timeoutTimer = new Timer();
timeoutTimer.ID = "timeouttimer";
timeoutTimer.Interval = 10000;
timeoutTimer.Tick += new EventHandler<EventArgs>(UpdarteTimer_Tick);
UpdatePanel timerUpdatePanel = new UpdatePanel();
timerUpdatePanel.ContentTemplateContainer.Controls.Add(timeoutTimer);
ScriptManager.GetCurrent(this.Page).RegisterAsyncPostBackControl(timeoutTimer);
this.Page.Form.Controls.Add(timerUpdatePanel);
}
base.OnInit(e);
}
I really need this on my website. Please help me. How can I create some routine in ASP.NET? Why I can't use Thread.Sleep in website and why is my timer do not work? Thank you
If you just want to update the interval of the Timer on Page.. you can just reference the one already created and set the Interval in either Page_Init or Page_Load like this ...
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" id="TimedPanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" id="DateStampLabel" />
</ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
UpdateTimer.Interval = 2000;
}
}
If it's ok, you can use js code
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<script type="text/javascript">
$(document).ready(function () {
setInterval(function () {
WebForm_GetElementById("MainContent_Label1").textContent = new Date().toLocaleString();
}, 1000);
});
</script>
Pay attention that Label ID and element name which you are looking for are different! (Honestly, I don't know why ASP.NET changes that ID)
After setting timer properties you have to call this line to start the timer:
timer.Start();
UPD:
I checked your UI timer and It works but It reload page every time when tick event happens.
<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick"></asp:Timer>
and in the code behind file:
protected void Page_Load(object sender, EventArgs e)
{
Timer1.Interval = 1000;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
Thus, I recommend using js method which I mentioned in another answer.
I have this AJAX button that I want to update some CSS. The problem is that the controls I want it to update are in a different file and can't be moved out of that file.
This is the panel whose CSS I want to update, which is located in the Site.master file:
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel ID="Panel2" runat="server" updatemode="Always">
<ContentTemplate>
<div id="updateThis" runat="server"><p>Test text</p></div>
</ContentTemplate>
</asp:UpdatePanel>
This is the button, located in the Items.ascx file:
<asp:UpdateProgress runat="server" ID="PageUpdateProgress">
<ProgressTemplate>
<img class="ajax-loader" src="/Images/ajax-loader.gif" alt="Loading..." />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="Panel3" runat="server" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateButton" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Button runat="server" OnClick="UpdateButton"
OnClientClick="hideButton()" Text="Update"
class="update" ID="UpdateButton" name="UpdateButton"
type="submit" ></asp:Button>
</ContentTemplate>
</asp:UpdatePanel>
This is the Items.ascx.cs method that is UpdateButton
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.Controls[0].FindControl("updateThis");
div.Style.Add("color", "#ff0000");
}
When I click the button it doesn't end up working correctly. As of right now, with the AJAX UpdateProgress template, it shows the loading GIF and then the GIF disappears and the text never changes color.
EDIT
Hopefully this will give a better idea of where things might be going wrong:
THIS WORKS
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.FindControl("updateThis");
div.Style.Add("color", "#ff0000");
UpdateButton.Text = "Done!";
}
I had #updateThis in the FindControl() method. Don't be like me!
You should add the runat="server" attribute to the div control, to make it visible in code-behind:
<div id="updateThis" runat="server"><p>Test text</p></div>
You can also remove Controls[0] in the event handler (but it works if you keep it, according to my tests):
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.FindControl("updateThis");
div.Style.Add("color", "#ff0000");
}
i wanted to use a timer in a program i'm working on, but it always stops after 1 tick !! can you give me any tips to make it repeat unstoppably (or until i want it to) please ??
this is my code:
int i = 20;
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "(20)";
}
protected void Timer1_Tick(object sender, EventArgs e)
{
i--;
Label1.Text = "(" + i + ")";
if (i == 0)
{
Session["Profession"] = "Visiteur";
Response.Redirect("Acceuil.aspx");
}
Edit: my HTML code :
<form id="form1" runat="server">
<div><center>
<span class="style1">message</span><br
class="style1" />
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick" >
</asp:Timer>
<asp:Timer ID="Timer2" runat="server" Interval="1000">
</asp:Timer>
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:LinkButton ID="LinkButton1" runat="server" onclick="LinkButton1_Click"
PostBackUrl="~/Acceuil.aspx">Retour</asp:LinkButton>
<br />
</center>
</div>
</form>
Edit2: what i want to do is the normal redirecting code, count to 20 and refreshing every second (to show to user how much secs left) and at the end it redirects to a new page, but it wasn't working, so i was wondering why ??
and i think i got my answer from #Andrei Rînea, and thank you everyone for your help : )
Edit3: Solved and here is the code :
static int i = 20;
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
Label1.Text = "20";
}
protected void Timer1_Tick(object sender, EventArgs e)
{
i--;
Label1.Text = i.ToString();
if (i == 0)
{
i = 20;
Session["Profession"] = "Visiteur";
Response.Redirect("Acceuil.aspx");
}
}
Thanks everyone again : )
Please use the following code :
static int i = 20;
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
Label1.Text = "(20)";
}
protected void Timer1_Tick(object sender, EventArgs e)
{
i--;
Label1.Text =i.ToString();
if (i == 0)
{
Session["Profession"] = "Visiteur";
Response.Redirect("Acceuil.aspx");
}
}
your HTML code should be like :
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Timer ID="Timer1" runat="server" ontick="Timer1_Tick" Interval="1000">
</asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
I'm going to assume here that you are wishing to have a process that ticks away on your server in the background.
I'm also going to assume you've tried to add this to your Webform.
If so, the issue you have encountered, is that your Webform object only exists for the short time that it is processing your request, after which it is disposed of - including your timer.
If I'm correct, you'd probably like to take a look at Quartz.Net:
http://www.mikesdotnetting.com/article/254/scheduled-tasks-in-asp-net-with-quartz-net
You are trying to run client side code on the server. You need to do this in JavaScript instead.
The C# code will be run just before rendering the page and not longer. You probably believe the code will run as long as the visitor is on the page which is not the case.
I'm trying to implement in my web form an easy wait function, it works, but not as I would.
My code is this:
for(int i = 0; i<5; i++)
{
Label1.Text = "Invio: " +i;
System.Threading.Thread.Sleep(6000);
}
The problem is that Label Text doesnt' change every 6 seconds.
This script should use 30second and change the label text in this manner:
"Invio: i" every 6 seconds.
Instead it waits 6 seconds and then it change the text in "Invio 4".
Why?
The reason this happens is because of the view state . Before you render your page the back-end code is executed, after it finishes, the DOM start to render and then your page is ready. That means your page won't refresh the label value every N seconds, because it has been already set. If you want to change the value of this dynamically you should use some front-end method as JavaScript or jQuery. If you want this approach - comment so I can make a fiddle for you.
Also this would be helpful for you - ViewState
Here is a fiddle to check if you want something like this - Fiddle demo
var count = 1;
time = setInterval(function(){
document.getElementById("label1").innerHTML="Indio: " + count;
count+= 1;
if (count == 5)
{
clearInterval(time);
}
},6000);
Back end like this:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Timer1_Tick(object sender, EventArgs e)
{
Label txt = Label1;
int i = Convert.ToInt32(txt.Text);
if (i == 4)
{
Timer1.Enabled = false;
}
else
{
i++;
Label1.Text = i.ToString();
}
}
}
and front-end is like this:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick" Enabled="true" Interval="6000">
</asp:Timer>
<asp:Label ID="Label2" runat="server" Text="Invio: "></asp:Label>
<asp:Label ID="Label1" runat="server" Text="0"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" />
</Triggers>
</asp:UpdatePanel>
</asp:Content>
This will loop 5 times with a 6 second interval.
Timer on page will trigger a postback, server side will execute and will update an updatepanel.
Unfortunately there is no easy way of doing that kind of thing purely using basic Asp.Net webforms (unless you use Asp.Net Webforms AJAX - which I personally find very confusing).
Assuming you are trying to provide some feed back to your user, about a long running operation, I'd use a combination of javascript (using JQuery Ajax for example) and a simple page to poll if the task is done, then redirect to result page.
I'm trying to make an webapplication where you see an Ajax countdown timer. Whenever I push a button the countdown should go back to 30 and keep counting down.
Now the problem is whenever I push the button the timer keeps counting down for a second or 2 and most of the time after that the timer keeps standing on 30 for to long.
WebForm code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="geen verbinding"></asp:Label>
<br />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<br />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick">
</asp:Timer>
</form>
Code Behind:
static int timer = 30;
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = timer.ToString();
}
protected void Timer1_Tick(object sender, EventArgs e)
{
timer--;
}
protected void Button1_Click(object sender, EventArgs e)
{
timer = 30;
}
Hope somebody knows what the problem is and if there is anyway to fix this.
Thanks in advance!
Why don't you implement the Timer entirely on the ClientSide? Can you explain why it has to be a callback? What does it need to do on the Server?
<script type="text/javascript" language="javascript">
var timer = 0;
function resetTimer() {
timer = 0;
timerTick();
}
function timerTick() {
var target = document.getElementById("timerResult");
target.innerHTML = timer++;
window.setTimeout("timerTick()", 1000);
}
</script>
And in the body tag...
<body onload="timerTick();">
And somewhere to display
<div id="timerResult" >timerResult</div>
You justy have to add a button chich calls resetTimer(). I'll leave that to you