Udostępnij za pośrednictwem


Effective Use of AJAX and Threading while Creating ASP.NET controls

Effective
Use of AJAX and Threading while Creating ASP.NET controls

Despite
of having excellent resources for parallel programming, we as a legacy programmer are used to of writing single treaded application which is not using our Multi core processors machines.

Some days back, I was writing a RSS Feed User Control which had to feed updates from multiple sites. As the client’s main concern was performance with his existing application so we had to make this control keeping performance at first
priority.

Problem Statement: we have to create a control which would show feeds from multiple urls. But initially when the user goes to the page he would be able to see only top 10 feeds, when user clicks on view more we have to make
AJAX request to append next top 10 results in the panel. This Control will have dropdown which will have Feed Titles of the feed when user changes dropdown value; again it should be an Ajax call to show top 10 updates from that feed. From
the Web Request point of view, we used AJAX for making light server calls. We can use AJAX in .NET web applications through 3 ways.

1. Using inbuilt Update Panels controls- It’s very easy to implement AJAX using update panel control but when we use it, it will call full page life cycle for each Ajax request which would be a costly operations so we dropped out this option.

2.Using JQuery Ajax functions- This approach seems to be better than the previous approach but while using AJAX with Jquery, Jquery internally calls some function which makes it little less efficient.

3.Using XmlHttp Request- XMLHttp requests are the base of AJAX, so if we go with this approach we can create ajax request of our own. This provides us more control over the prior methods and performance wise also this is best approach
for ajax calls.

we went with 3rd approach keeping performance in mind.

Html of the running code is attached as a attachment with this post.

whenever user clicks on view more link or select something from dropdown, we are making a xmlhttp request which send the request to AjaxRequestPage.aspx to get the updates based on filter criteria from dropdown. In case when user
clicks on view more option, we are appending the new string returned by AJAXRequestpage to div.

Below is a code to make an AJAX call using xmlHttpRequest object. request.ResponseText will have the complete data that we can show anywhere in the browser.

var request = new XMLHttpRequest();

request.open('GET', 'https://www.bing.com/', true);

request.onreadystatechange = function (aEvt) {

if (request.readyState == 4) {

if(request.status == 200)

console.log(request.responseText)

else

console.log('Error', request.statusText);

}

};

req.send(null);

the AJAXRequestPage will handle the ajax request and will intern call the method which will returns the string that needs to be append to the div.

While XML Http Requests take care of making Asynchronous server calls but within each server request we should be able to use multi core processors to get the results very fast as our requirement was to get updates from multiple url feeds.
we ahve used C#.NET Threading classes to get updates from multiple feed in multithreading environment.Before starting on coding portion, it would be good to understand the Class the we used for handling threads in multi threaded environment.

ManualResetEvent Class :

ManualResetEvent allows threads to communicate with each other by signalling. Typically, this communication concerns a task which one thread must complete before other threads can proceed. When a thread begins an activity that must complete before other threads proceed, it calls Reset to put ManualResetEvent in the nonsignaled state. This thread can be thought of as controlling the ManualResetEvent. Threads that call WaitOne on the ManualResetEvent will block, awaiting the signal. When the controlling thread completes the activity, it calls Set to signal that the waiting threads can proceed. All waiting threads are released.

Once it has been signaled, ManualResetEvent remains signalled until it is manually reset. That is, calls to WaitOne return immediately.

You can control the initial state of a ManualResetEvent by passing a Boolean value to the constructor, true if the initial state is signalled and false otherwise. Below statement will process each url that user has subscribed for and then assign
separate threads to execute LoadT function. After executing this loop the value of activeThreads variable will be equal to number of urls we are feeding.

ManualResetEvent
isDone = new ManualResetEvent(false);// parameter value false means it is in
reset state(=> thread will wait at waitone statement)

foreach
(var url in GetUrls())

{

ThreadPool.QueueUserWorkItem(this.LoadT, url);

this.activeThreads++;

}

the below statements will create one more thread which will execute FinishWork function and Main thread will wait till the time some of the running thread calls the isDone(ManualRestEvent) to set state.

ThreadPool.QueueUserWorkItem(this.FinishWork);

this.isDone.WaitOne(10000); //Main thread will wait here till the time any of
the running thread change the state to set state.

LoadT Method will be called by Multiple thread and each thread will decrement the value of activeThreads.Once the value of activeThreads reachces 0, FinishWork method which is also executing will set the ManualResetEvent evnt and after
that main thread will resume from waitone statement and do rest of task. The reason behind using waitone statement in this example was all the Threads executing LoadT are trying to modify shared variable and Main thread will wait on waitone
till the time that shared variable is updated by all the threads. Here in RSS feed webpart we are Adding data in List and once list get data from all the thread main thread will resume from waitone and execute the rendering logic for RSS feed control.

private
void LoadT()

{

//Process RSS Feeds here

this.activeThreads
--;

}

private
void FinishWork(object o)

{

while (this.activeThreads > 0)

{

}

this.isDone.Set();

}

Here
is how the User control looks like:

 Full code for the implementation of RSSFeed Usercontrol is there in attachement.let me know in case of any further confusions.

Happy Coding :-)