I have implemented a system in the CMS I've developed to automatically validate links in the link library within the CMS. As the validation involves attempting to connect to every link in the collection, it naturally takes some time, so I want to have a progress updater which keeps the user informed of how the link validator is getting along. I use a timer on a page which calls a function on the server to return the link currently being browsed, and the number of the link within the total. This information is then displayed asynchronously in an UpdatePanel. This works, but there is one problem. When the "check links" button is clicked to initiate the checking process, there is a long delay before any progress update is displayed. By the time the progress update starts to work, most of the links have already been checked. I can see that the timed callback is not being activated during this pause. I'm wondering if anyone has any suggestions as to why this is occurring, and if there's a solution.
Relevant code is as follows. ASP.NET:
<asp:Button runat="server" ID="btnCheck" OnClick="btnCheck_Click" Text="Check links..." />
<asp:Timer ID="Timer1" runat="server" Interval="500" OnTick="Timer1_OnTick" />
<br /><br />
<asp:UpdatePanel runat="server" ID="upProgress" UpdateMode="Conditional" ChildrenAsTriggers="false">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Literal runat="server" ID="litProgress" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel runat="server" ID="upCheckLinks" UpdateMode="Conditional" ChildrenAsTriggers="false" >
<ContentTemplate>
<asp:GridView ID="gv1" runat="server" AutoGenerateColumns="false">
...<!--the links with problems displayed here-->...
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
The code-behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnCheck_Click(object sender, EventArgs e)
{
BindData();
}
protected void Timer1_OnTick(object sender, EventArgs e)
{
if (Session["Working"] != null)
try
{
string msg = "Checking link: " + Session["LinkCheck"].ToString() + "<br />";
msg += Session["CheckLinkNum"].ToString() + " of " + Session["CheckLinkTotal"].ToString() + " links";
litProgress.Text = msg;
}
catch { }
else
litProgress.Text = "Time is:" + DateTime.Now.ToLongTimeString();
}
private void BindData()
{
Session["Working"] = true;
int linknum = 0;
DataTable dt = Link.Search(-1,-1); //this returns a DataTable of all links in the CMS
Session["CheckLinkTotal"] = dt.Rows.Count;
dt.Columns.Add(new DataColumn("Error"));
foreach (DataRow dr in dt.Rows)
{
linknum++;
Session["CheckLinkNum"] = linknum;
string stURL = dr["URL"].ToString();
string stErr=CheckURL(stURL);
if (stErr == "")
dr.Delete();
else
dr["Error"] = stErr;
}
gv1.DataSource = dt;
gv1.DataBind();
Session["Working"] = null;
upProgress.Update();
upCheckLinks.Update();
}
protected string CheckURL(string stURL)
{
HttpWebRequest URLReq;
HttpWebResponse URLRes;
Session["LinkCheck"] = stURL;
try
{
URLReq = (HttpWebRequest)HttpWebRequest.Create(stURL);
URLRes = (HttpWebResponse)URLReq.GetResponse();
return "";
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ServerProtocolViolation)
return ""; //server protocol violations are not a fatal problem. Usually the page displays as normal, so we ignore these errors.
return ex.Message.ToString();
}
}
protected void btnSearch_Click(object sender, EventArgs e)
{
BindData();
}