I have an asp.net page that reads in a file line by line. Each line is processed and either added to a db or discarded. After this is completed I am adding to a counter so I know the number of lines processed, then setting HttpContext.Current.Cache["TotalRecords"] equal to the counter.
In my ASP page I have a Page Method called GetLatestCount (see below).
[System.Web.Services.WebMethod]
public static int GetLatestCount()
{
int dt=0;
try
{
dt = (int)HttpContext.Current.Cache["TotalRecs"];
}
catch (Exception ex)
{
console.log();
}
return (dt);
}
In my Client side script I am polling that PageMethod using Javascript. Not AJAX or JQUERY.
<script language="javascript" type="text/javascript">
function Check()
{
// Call the static page method.
try
{
PageMethods.GetLatestCount(OnSucceeded, OnFailed);
}
catch (ex)
{
console.log();
}
}
function OnSucceeded(result, userContext, methodName)
{
try
{
// Parse the page method's result and the embedded
// hidden value to integers for comparison.
var TotalRecs = parseInt(result);
if (TotalRecs == 999999)
{
lblTotalRecs.innerHTML = "";
}
else
{
lblTotalRecs.innerHTML = "Processing Record: " + TotalRecs;
setTimeout("Check()", 500);
}
}
catch(ex)
{
}
}
function OnFailed(error, userContext, methodName)
{
alert(error);
}
The file I'm reading in has 4000+ lines so it takes a while to process. The javascript polling processes twice then doesn't seem to trigger again until half the file is processed (2065 lines read) or up to 30 seconds. But even that is sporadic. Sometimes after 3000 lines read or 1000 lines read. After that it works the way I imagine it should and keeps track of the file's progress. Any ideas on why it it only gets the last part of the file and not the first? How do I get this to work in the beginning of the process?
Related
These sequences of actions work with Thread.Sleep, somewhere in 1 second, somewhere in 2 seconds. I think using Thread.Sleep/Task.Delay is not good. Because it can be performed differently on different computers. How do I execute these sequences without using Thread.Sleep?
Or it is OK to using Thread.Sleep/Task.Delay?
private async void ButtonFind_Click(object sender, EventArgs e)
{
//Action1
string jsScript1 = "document.getElementById('story').value=" + '\'' + textFind.Text + '\'';
await chrome.EvaluateScriptAsync(jsScript1);
//Action2
string jsScript2 = "document.querySelector('body > div.wrapper > div.header > div.header44 > div.search_panel > span > form > button').click();";
await chrome.EvaluateScriptAsync(jsScript2);
//Action3
Thread.Sleep(1000); //it is necessary to set exactly 1 seconds
string jsScript3 = "document.getElementsByTagName('a')[2].click();";
await chrome.EvaluateScriptAsync(jsScript3);
//Action4
Thread.Sleep(2000); //it is necessary to set exactly 2 seconds
string jsScript4 = "document.querySelector('#dle-content > div.section > ul > li:nth-child(3)').click();";
await chrome.EvaluateScriptAsync(jsScript4);
}
I tried to use task expectations, but it didn't help me
...
var task4 = chrome.EvaluateScriptAsync(jsScript4);
task4.Wait();
I also tried to use DOM rendering expectations, which didn't help either
string jsScript4 = #"
if( document.readyState !== 'loading' ) {
myInitCode();
} else {
document.addEventListener('DOMContentLoaded', function () {
myInitCode();
});
}
function myInitCode() {
var a = document.querySelector('#dle-content > div.section > ul > li:nth-child(3)').click();
return a;
}
";
chrome.EvaluateScriptAsync(jsScript4);
My addition (21.04.2022)
In third action instead of using Thread.Sleep, im using "While" loop
Here the algorithm is correct, but for some reason, after pressing the application button, the application is hanging
bool test = false;
while(test == false)
{
string myScript = #"
(function(){
var x = document.getElementsByTagName('a')[1].outerText;
return x;
})();
";
var task = chrome.EvaluateScriptAsync(myScript);
task.ContinueWith(x =>
{
if (!x.IsFaulted)
{
var response = x.Result;
if (response.Success == true)
{
var final = response.Result;
if (final.ToString() == textFind.Text)
{
MessageBox.Show("You found the link");
test = true;
}
else
{
MessageBox.Show("You do not found the link");
}
}
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
My addition (23.04.2022)
string jsScript1 = "document.getElementById('story').value=" + '\'' + textFind.Text + '\'' + ";"
+ #"
Promise.resolve()
.then(() => document.querySelector('body > div.wrapper > div.header > div.header44 > div.search_panel > span > form > button').click())
.then(() => { var target = document.body;
const config = {
childList: true,
attributes: true,
characterData: true,
subtree: true,
attributeFilter: ['id'],
attributeOldValue: true,
characterDataOldValue: true
}
const callback = function(mutations)
{
document.addEventListener('DOMContentLoaded', function(){
if(document.getElementsByTagName('a')[1].innerText=='Troy')
{
alert('I got that link');
}
}, true);
};
const observer = new MutationObserver(callback);
observer.observe(target, config)});
";
var task1 = chrome.EvaluateScriptAsPromiseAsync(jsScript1);
task1.Wait();
Using a MutationObserver wrapped in a promise, using EvaluateScriptAsPromiseAsync to evaluate promise. Also didnt help.
I came to the conclusion that JavaScript does not save the code when clicking on a search button or after going to another page. How do I save the JavaScript code/request and continue it after clicking on a search button or after going to another page?
As your JavaScript causes a navigation you need to wait for the new page to load.
You can use something like the following to wait for the page load.
// create a static class for the extension method
public static Task<LoadUrlAsyncResponse> WaitForLoadAsync(this IWebBrowser browser)
{
var tcs = new TaskCompletionSource<LoadUrlAsyncResponse>(TaskCreationOptions.RunContinuationsAsynchronously);
EventHandler<LoadErrorEventArgs> loadErrorHandler = null;
EventHandler<LoadingStateChangedEventArgs> loadingStateChangeHandler = null;
loadErrorHandler = (sender, args) =>
{
//Actions that trigger a download will raise an aborted error.
//Generally speaking Aborted is safe to ignore
if (args.ErrorCode == CefErrorCode.Aborted)
{
return;
}
//If LoadError was called then we'll remove both our handlers
//as we won't need to capture LoadingStateChanged, we know there
//was an error
browser.LoadError -= loadErrorHandler;
browser.LoadingStateChanged -= loadingStateChangeHandler;
tcs.TrySetResult(new LoadUrlAsyncResponse(args.ErrorCode, -1));
};
loadingStateChangeHandler = (sender, args) =>
{
//Wait for while page to finish loading not just the first frame
if (!args.IsLoading)
{
browser.LoadError -= loadErrorHandler;
browser.LoadingStateChanged -= loadingStateChangeHandler;
var host = args.Browser.GetHost();
var navEntry = host?.GetVisibleNavigationEntry();
int statusCode = navEntry?.HttpStatusCode ?? -1;
//By default 0 is some sort of error, we map that to -1
//so that it's clearer that something failed.
if (statusCode == 0)
{
statusCode = -1;
}
tcs.TrySetResult(new LoadUrlAsyncResponse(statusCode == -1 ? CefErrorCode.Failed : CefErrorCode.None, statusCode));
}
};
browser.LoadingStateChanged += loadingStateChangeHandler;
browser.LoadError += loadErrorHandler;
return tcs.Task;
}
// usage example
private async void ButtonFind_Click(object sender, EventArgs e)
{
//Action1
string jsScript1 = "document.getElementById('story').value=" + '\'' + textFind.Text + '\'';
await chrome.EvaluateScriptAsync(jsScript1);
//Action2
string jsScript2 = "document.querySelector('body > div.wrapper > div.header > div.header44 > div.search_panel > span > form > button').click();";
await Task.WhenAll(chrome.WaitForLoadAsync(),
chrome.EvaluateScriptAsync(jsScript2));
//Action3
string jsScript3 = "document.getElementsByTagName('a')[2].click();";
await Task.WhenAll(chrome.WaitForLoadAsync(),
chrome.EvaluateScriptAsync(jsScript3));
//Action4
string jsScript4 = "document.querySelector('#dle-content > div.section > ul > li:nth-child(3)').click();";
await chrome.EvaluateScriptAsync(jsScript4);
}
You never must work with sleep because time changes between computers and, even in the same computer, a web page may be differ the time required to load.
I work a lot with scraping and IMO the best focus to manage this is working from JavaScript side. You inject/run your JavaScript to fill controls, click buttons...
With this focus, the problem is that navigations make you lose the state. When you navigate to other page, your JavaScript start from scratch. I revolve this sharing data to persist between JavaScript and C# through Bound Object and injecting JavaScript.
For example, you can run action 1, 2 and 3 with a piece of JavaScript code. Before click button, you can use your Bound Object to tell to your C# code that you are going to second page.
When your second page are loaded, you run your JavaScript for your second page (you know the step and can inject the JavaScript code for your 2 page).
In all cases, your JavaScript code must have some mechanism to wait. For example, set a timer to wait until your controls appears. In this way, you can run your JavaScript without wait to the page is fully loaded (sometimes this events are hard to manage).
UPDATE
My scraping library is huge. I'm going to expose pieces that you need to do the work but you need to assemble by yourself.
We create a BoundObject class:
public class BoundObject
{
public BoundObject(IWebBrowser browser)
{
this.Browser = browser;
}
public void OnJavaScriptMessage(string message)
{
this.Browser.OnJavaScriptMessage(message);
}
}
IWebBrowser is an interface of my custom browser, a wrapper to manage all I need. Create a Browser class, like CustomBrowser, for example, implementing this interface.
Create a method to ensure your Bound Object is working:
public void SetBoundObject()
{
// To get events in C# from JavaScript
try
{
var boundObject = new BoundObject();
this._browserInternal.JavascriptObjectRepository.Register(
"bound", boundObject, false, BindingOptions.DefaultBinder);
this.BoundObject = boundObject;
}
catch (ArgumentException ex)
{
if (!ex.ParamName.Identical("bound"))
{
throw;
}
}
}
_browserInternal is the CefSharp browser. You must run that method on each page load, when you navigate. Doing that, you have a window.bound object in JavaScript side with an onJavaScriptMessage function. Then, you can define a function in JavaScript like this:
function sendMessage(msg) {
var json = JSON.stringify(msg);
window.bound.onJavaScriptMessage(json);
return this;
};
You can send now any object to your C# application and manage in your CustomBrowser, on OnJavaScriptMessage method. In that method I manage my custom message protocol, like a typical one in sockets environment or the windows message system and generate a OnMessage that I implement in classes inheriting CustomBrowser.
Send information to JavaScript is trivial using ExecuteScriptAsync of CefSharp browser.
Going further
When I work in an intense scraping job. I create some scripts with classes to manage the entire Web to scrap. I create classes, for example, to do login, navigate to different sections, fill forms... like if I was the owner of the WebSite. Then, when page load, I inject my scripts and I can use my own classes in the remote WebSite making scraping... piece of cake.
My scripts are embedded resources so are into my final executable. In debug, I read them from disk to allow edit+reload+test until my scripts works fine. With the DevTools you can try in the console until you get the desired source. Then you add into your JavaScripts classes and reload.
You can add simple JavaScript with ExecuteScriptAsync, but with large files appears problems escaping quotes...
So you need insert an entire script file. To do that, implement ISchemeHandlerFactory to create and return an IResourceHandler. That resource handler must have a ProcessRequestAsync in which you receive a request.Url that you can use to locale your scripts:
this.ResponseLength = stream.Length;
this.MimeType = GetMimeType(fileExtension);
this.StatusCode = (int)HttpStatusCode.OK;
this.Stream = stream;
callback.Continue();
return true;
stream maybe a MemoryStream in which you write the content of your script file.
I am working on a project at work and I am using CefSharp to connect c# to JS due to a restriction that I am not allowed to use external servers or even a localhost server to host php or other scripting language. The goal I need to reach is I have an async method in c# that works it is reading the csv that i need to accomplish my job, I have debug stepped through the values and its fine. it returns a Task In my js file which called the method to read the local file and return an array of strings to be handled. I get a pending promise, when i used await the pending promise sits there and halts my browser, I have been searching the internet for help and I havent found anything that seems to work. ill post as much of the current code as I can, I need to find a solution for this or atleast some good pointers to get the value from c# to resolve in the js script so that I can move forward.
//C# Code::
public Task<string[]> GetCSV()
{
return GetCSVAsync(Encoding.UTF8, pB.GetDefaultPath(PathSelection.AppPathWeb) + "\\MatId\\Includes\\misc\\questions.csv");
}
public async Task<string[]> GetCSVAsync(Encoding encoding, string path)
{
string[] lines = new string[1];
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, DefaultOptions))
{
using (StreamReader reader = new StreamReader(stream, encoding))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
lines = AddLineToLines(lines, line);
}
}
}
return lines;
}
/// <summary>
/// This code is opensourced.
/// </summary>
/// <param name="linesinarray">lines array</param>
/// <param name="linetoadd">line to add to the lines array</param>
/// <returns>lines array with new value in length</returns>
private string[] AddLineToLines(string[] linesinarray, string linetoadd)
{
if (String.IsNullOrWhiteSpace(linesinarray[0]))
{
linesinarray[0] = linetoadd;
return linesinarray;
}
else
{
string[] temp = new string[linesinarray.Length + 1];
for (int i = 0; i < linesinarray.Length; i++)
{
temp[i] = linesinarray[i];
}
temp[temp.Length - 1] = linetoadd;
return temp;
}
}
//JS Code::
//one attempt::
async function getCSVData() {
try {
var xValue = jsDBConnection.getCSV().then(function (res) {
console.log(res);
});
} catch (e) {
console.log(e.message);
}
}
//Attempt 2::
async function getCSVData() {
try {
var xValue = await jsDBConnection.getCSV();
return xValue;
} catch (e) {
console.log(e.message);
}
}
All of these call c# and run through the c# methods However on return the promise is pending statused and value is undefined, and then jquery runs in an infanite loop until either I pause execution or kill the process it never returns any value.
Im new to async programming and I feel that i can get it working but I dont know where I went wrong... I need some help and I am asking fto help me find what I did wrong.
Thank you,
Jesse Fender
I am working with pngjs through many of it's methods. Most of the time, they work fine. However, like in the following example, I get an error: "Stream is not writable"
var fs = require('fs'),
PNG = require('pngjs').PNG;
var dst = new PNG({width: 100, height: 50});
fs.createReadStream('http://1.1m.yt/hry7Eby.png') //download this picture in order to examine the code.
.pipe(new PNG())
.on('parsed', function(data) {
console.log(data);
});
This case is not singular, I get this error on 1 random png image once a day, through all of pngjs methods, and that error obviously crashes my app.
(note: you can't use the http link I gave you with a readStream, you will have to download & rename it and do something like):
fs.createReadStream('1.png')
Thank you for your time and effort.
This seems to be a bug in the library, though I'm wary of saying so as I'm no expert in PNGs. The parser seems to complete while the stream is still writing. It encounters the IEND, and so calls this:
ParserAsync.prototype._finished = function() {
if (this.errord) {
return;
}
if (!this._inflate) {
this.emit('error', 'No Inflate block');
}
else {
// no more data to inflate
this._inflate.end();
}
this.destroySoon();
};
If you comment out the this.destroySoon(); it finishes the image correctly, instead of eventually calling this function:
ChunkStream.prototype.end = function(data, encoding) {
if (data) {
this.write(data, encoding);
}
this.writable = false;
// already destroyed
if (!this._buffers) {
return;
}
// enqueue or handle end
if (this._buffers.length === 0) {
this._end();
}
else {
this._buffers.push(null);
this._process();
}
};
...which would otherwise end up setting the stream.writeable to false, or, if you comment that out, to pushing a null value into the _buffers array and screwing up the ChunkStream._processRead.
I'm fairly certain this is a synchronicity problem between the time the zlib parser takes to complete and the time the stream takes to complete, since if you do this synchronously it works fine:
var data = fs.readFileSync('pic.png');
var png = PNG.sync.read(data);
var buff = PNG.sync.write(png);
fs.writeFileSync('out2.png', buff);
To preface this - it is a school semester project so if it is a little hacky, I apologize, but I believe it is a fun and interesting concept.
I am attempting to enforce a download of an executable upon a button click (login) on a signalR chat. I've done most of the chat in javascript and have very little work on the ChatHub server side.
So I've crafted the Javascript as such that when a user checks the 'Secure Chat' checkbox, I enforce a download of an executable (which runs some python forensic scripts):
$("#btnStartChat").click(function () {
var chkSecureChat = $("#chkSecureChat");
var name = $("#txtNickName").val();
var proceedLogin = false;
if (chkSecureChat.is(":checked")) {
proceedLogin = chatHub.server.secureLogin();
isSecureChat = true;
} else {
proceedLogin = true;
}
The chatHub.server.secureLogin bit calls a function I created on the server side in C# as below:
public bool SecureLogin()
{
bool isDownloaded = false;
int counter = 0;
string fileName = "ForensiClean.exe";
string userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string downloadPath = (userPath + "\\Downloads\\" + fileName);
// try three times
while(isDownloaded == false && counter < 3)
{
if (System.IO.File.Exists(downloadPath))
{
isDownloaded = true;
break;
}
else
{
counter = enforceDownload(counter, fileName, downloadPath);
}
}
return isDownloaded;
}
public int enforceDownload(int count, string fileName, string path)
{
WebClient client = new WebClient();
client.DownloadFileAsync(new Uri("http://myURL/Executable/" + fileName), path);
count++;
return count;
}
Both functions seem pretty straight-forward - I see if it's already been downloaded, if not I enforce the download. It works while in development. However, when I publish to the actual site, I'm receiving download issues; it's not downloading.
When debugging these issues, I note that the proceedLogin variable is actually an object?!?! (as shown in the image). Please help with any ideas, I'm stumped.
It looks like proceedLogin is a promise object.
Try this:
if (chkSecureChat.is(":checked")) {
chatHub.server.secureLogin().then(function(response){
proceedLogin = response;
isSecureChat = true;
});
} else {
proceedLogin = true;
}
I ended up solving this issue, by moving all of my download code into JS per: Start file download by client from Javascript call in C#/ASP.NET page? It is, after all, a school project - so I gotta get moving on it.
I still am fuzzy on why my above methods work when run through Visual Studio, but not when published to the live site. Thank you #Cerbrus and #SynerCoder for your responses.
I have searched for several days now, and have tried about every solution that I could find. I know this is something I am not doing correctly, however, I am not sure what the correct way is.
I have an ASP.Net C# web site, running on .Net Framework 4.5. I have a link button on a form, that when clicked fires off a long running process using the ThreadPool. I have a delegate callback setup, and the code does fire when the process is canceled or when it finishes. (I am using the Cancelation Token for canceling the process and the process is Active Reports in case that matters.)
Like I said, everything works great, except for when the callback code fires it does not execute the javascript. (FYI -- this is NOT a javascript callback, just trying to fire off some javascript code when the process finishes.)
Here is the code that i start the report...
string sThreadID = Thread.CurrentThread.ManagedThreadId.ToString();
ThreadPool.QueueUserWorkItem(new WaitCallback(StartReport), cts.Token);
Here is the code for the StartReport....
public static void StartReport(object obj) {
try {
OnTaskCompleteDelegate callback = new OnTaskCompleteDelegate(OnTaskComplete);
BoyceReporting.CallReport(boyce.BoyceThreadingEnvironment.OBRO, "THREADING");
if (boyce.BoyceThreadingEnvironment.CTS.Token.IsCancellationRequested) {
boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute = "alert('Report Canceled By User');";
callback("CANCELED");
} else {
callback("FINISHED");
}
} catch {
throw;
}
}
Here is the code for the CallBack code.....
public static void OnTaskComplete(string ReportResult) {
try {
sReportResult = ReportResult;
if (ReportResult == "CANCELED") {
// In case we need to do additional things if the report is canceled
}
string sThreadID = Thread.CurrentThread.ManagedThreadId.ToString();
boyce.BoyceThreadingEnvironment.THISPAGE.ClientScript.RegisterStartupScript(boyce.BoyceThreadingEnvironment.THISPAGE.GetType(), "FireTheScript" + DateTime.Now.ToString(), boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute, true);
ScriptManager.RegisterStartupScript(boyce.BoyceThreadingEnvironment.THISPAGE, boyce.BoyceThreadingEnvironment.THISPAGE.GetType(), "DisplayReport" + DateTime.Now.ToString(), boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute, true);
} catch {
throw;
}
}
Here is the issue that I am having.....
Everything works fine except i can not get the last line of code to fire the script.
ScriptManager.RegisterStartupScript
Here is what I think is happening.....
From looking at the thread ID, I am sure the reason that the code is not firing is because the ScriptManager code that I am trying to fire in the Call Back event is on a different thread, other than the main thread.
Here is my question(s).....
(1) Am I correct in why this is not firing the JavaScript
(2) How can I (from inside of the CallBack) get this JavaScript to fire? Is there a way to force this to execute on the main Thread?
It's not firing in JS because you're spinning off a new thread. In the meantime, the request has long since returned to the client and closed the connection. By the time the thread tries to write something out to the Response, it's already finished.
Instead of doing it this way, just have your button click (or whatever it is that kicks off the report), inside of an UpdatePanel. Then, you don't need to fire off a new thread.
Here is the cod I used in the C# Code Behind to call the web service to start monitoring this process.
----------------------------------------------------------------------------------------------
CurrentSession.bIsReportRunning = true;
ScriptManager.RegisterStartupScript(this, this.GetType(), "WaitForReport" + DateTime.Now.ToString(), "jsWaitOnCallReport();", true);
MultiThreadReport.RunTheReport(HttpContext.Current, CurrentSession, this, oBRO);
Here is the code that calls the method, using the threadpool, and the method called..
----------------------------------------------------------------------------------------------
ThreadPool.QueueUserWorkItem(new WaitCallback(StartReport), cts.Token);
public static void StartReport(object obj) {
try {
OnTaskCompleteDelegate callback = new OnTaskCompleteDelegate(OnTaskComplete);
BoyceReporting.CallReport(boyce.BoyceThreadingEnvironment.OBRO, "THREADING");
HttpContext.Current = boyce.BoyceThreadingEnvironment.CONTEXT;
if (boyce.BoyceThreadingEnvironment.CTS.Token.IsCancellationRequested) {
boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute = "alert('Report Canceled By User');";
boyce.BoyceThreadingEnvironment.SESSION.bIsReportRunning = false;
callback("CANCELED");
} else {
boyce.BoyceThreadingEnvironment.SESSION.bIsReportRunning = false;
callback("FINISHED");
}
} catch {
throw;
}
}
Here is the web service method I created to monitor the process, with a built in safety net
--------------------------------------------------------------------------------------------
[WebMethod(EnableSession = true)]
public string WaitOnReport() {
try {
HttpContext.Current = boyce.BoyceThreadingEnvironment.CONTEXT;
SessionManager CurrentSession;
CurrentSession = (SessionManager)boyce.BoyceThreadingEnvironment.SESSION;
DateTime dtStartTime = DateTime.Now;
DateTime dtCurrentTime = DateTime.Now;
if (CurrentSession != null) {
do {
// Build a safety limit into this loop to avoid an infinate loope
// If this runs longer than 20 minutes, then force an error due to timeout
// This timeout should be lowered when they find out what the issue is with
// the "long running reports". For now, I set it to 20 minutes but shoud be MUCH lower.
dtCurrentTime = DateTime.Now;
TimeSpan span = dtCurrentTime-dtStartTime;
double totalMinutes = span.TotalMinutes;
if (totalMinutes>=20) {
return "alert('Error In Creating Report (Time-Out)');";
}
} while (CurrentSession.bIsReportRunning == true);
// If all goes well, return the script to either OPEN the report or display CANCEL message
return CurrentSession.sScriptToExecute;
} else {
return "alert('Error In Creating Report (Session)');";
}
} catch {
throw;
}
}
And here is the JavaScript code I used to initiate the Web Service Call and Also The Postback
--------------------------------------------------------------------------------------------
function jsWaitOnCallReport() {
try {
var oWebService = BoyceWebService.WaitOnReport(jsWaitOnCallReport_CallBack);
} catch (e) {
alert('Error In Calling Report Screen -- ' + e);
}
}
function jsWaitOnCallReport_CallBack(result) {
try {
eval(result);
var myExtender = $find('ModalPopupExtenderPROGRESS');
if (myExtender != null) {
try {
myExtender.hide();
} catch (e) {
// Ignore Any Error That May Be Thrown Here
}
}
$find('PROGRESS').hide();
} catch (e) {
alert('Error In Opening Report Screen -- ' + e);
}
}
Hope this helps someone else out.. Like I said, I am not sure this is the best solution, but it works.. I would be interested in other solutions for this issue to try... Thanks.