Sunday, December 30, 2007

Enhance Data View Performance using Asynchronous Method

Currently I find a way how to enhance a performance to view 10.000 records which taken from Web service layer.

First of all, I can not using any caching because this data will change very often.
Every time the user change something, I need to refresh the data.

I can not use Sql Dependency because all the data are encapsulate on service layer.
I can not perform paging on service layer because it is not provided to me.


Finally, the only way is using Asynchronous Method.

The idea is to display the first page of the records and start retrieving others data asynchronously.

The next time the user want to perform, sorting, filtering or paging, It will force to finish all retreiving data.

This algorithm will force using user thinking time in retreiving huge records rather than forcing user to wait retrieving huge records every time even they just want to see the first page records.

Here is the Algorithm:
=================================
If ( ! IsPostback)
{
* Clear Data set from session
* Retrieve 1st page only and bind to data grid with next/previous paging style
* Create a delegate to retrieve the rest of data
* Start asynchronous call with BeginInvoke.
* Store that delegate and IAsynResult into session.
}
else
{ //( Postback) and user try to bind a data (Sorting, Paging, Filtering)
If (There still no data set in Session)
{
* Take delegate and IAsynResult
* Force delegate to finish by using EndInvoke(IAsynResult)
* Store the data set into Session.
* Bind to data grid with default paging style.
}
else
{
* directly use data set from session and bind to data grid with default paging style.
}
}
===============================

Note:
You may optimize this algorithm by getting a number of record first.
If the number of records is less or equal then the number of first page records, just store that data into session and bind it to data grid with default paging style.
You don't need to perform asynchronous call for this.


The only weakness of this methodology is it will be more thread in your application.

Sunday, December 16, 2007

Notify your custom application from CRM 3.0

This is one of the solution how you notify your application from Microsoft Dynamic CRM 3.0

1. Add Javascripts to notify your application from CRM Custom forms.
a. Open CRM 3.0

b. Go To Settings/ Customization

c. Select what entity you need ( Example phone, email, ...)

d. Go to forms and view on the left tab after you open your entity

e. Select the forms you want to add the scripts.

f. click add properties.

g. There is 2 available event handler (OnSave and OnLoad)

h. Put your javascript there
for example : window.opener('Notify on save');

i. Don't forget to check enable this event before you save it.

j. You may preview it before publish the changes.

g. Don't forget to publish - Action/Publish.

If you forget to publish, It will not take any changes you have made, even you have save it.

Friday, December 14, 2007

Better way to handle thread abort exception in Response.Redirect

private bool m_bIsTerminating = false;

protected void Page_Load(object sender, EventArgs e)
{
if (WeNeedToRedirect == true)
{
Response.Redirect(url, false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
m_bIsTerminating = true;
// remember to end the method here if
// there is more code in it

return;
}
}

protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
if (m_bIsTerminating == false)
base.RaisePostBackEvent(sourceControl, eventArgument);
}

protected override void Render(HtmlTextWriter writer)
{
if (m_bIsTerminating == false)
base.Render(writer);
}

Friday, November 16, 2007

Datagrid VS ViewState

This week, I try to optimized my web application which using 10 million record.

The first thing that I notice that EnableViewState by default is set to true.

So my datagrid will store all the view state into client. so every time there is postback or asyn postback, it will transfer heaps of data through networks. and It is not very efficient.

So I try to disable them by EnablingViewState = false.
However by disabling view state in the data , all the events in datagrid is not fired..


one of the solution is to disable view state on each item.
_dg.DataBind();
foreach (DataGridItem item in _dg.Items)
{
item.EnableViewState=false;
{


however, if your all commandArguments is not work,..

so the other solution is you need to bind every time in page back...

Tuesday, November 6, 2007

Resurrection

Just in case if you don't know.

Sometimes it is you may need to resurrects your object.
for example you want the object to clean itself gracefully everytime the object dies.

Here how to do resurrection....

public class MyBaseClass
{
Protected override void Finalize()
{
//TODO: Some Clean up....

GC.ReRegisterForFinalize(this);
}
}

By calling GC.ReRegisterForFinalize method, it will appends the address of the specified object to the end of the finalization queue. When GC detects that this object is unreadchable again, It will queue the object's pointer ob the freachable queue and Finalize method will get called again.

This is example show how to create an object that constantly resurrects itself and never dies...
which usually undesireable. It is far more common to conditionally set a root to a reference the object inside the finalize method.

Tuesday, October 30, 2007

Sys.WebForms.PageRequestManagerParserErrorException

“Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.”


this is the most annoyed error , That I ever had.

It happens only the first time after I restart my web application / after change web.config.

I still keep getting that error even I have try to alter my code based on this
--------------------------------------------------------------------------------------
  1. Calls to Response.Write():
    Place an or similar control on your page and set its Text property. The added benefit is that your pages will be valid HTML. When using Response.Write() you typically end up with pages that contain invalid markup.
  2. Response filters:
    The fix might just be to not use the filter. They're not used very often anyway. If possible, filter things at the control level and not at the response level.
  3. HttpModules:
    Same as response filters.
  4. Server trace is enabled:
    Use some other form of tracing, such as writing to a log file, the Windows event log, or a custom mechanism.
  5. Calls to Server.Transfer():
    I'm not really sure why people use Server.Transfer() at all. Perhaps it's a legacy thing from Classic ASP. I'd suggest using Response.Redirect() with query string parameters or cross-page posting.

Another way to avoid the parse error is to do a regular postback instead of an asynchronous postback. For example, if you have a button that absolutely must do a Server.Transfer(), make it do regular postbacks. There are a number of ways of doing this:

  1. The easiest is to simply place the button outside of any UpdatePanels. Unfortunately the layout of your page might not allow for this.
  2. Add a PostBackTrigger to your UpdatePanel that points at the button. This works great if the button is declared statically through markup on the page.
  3. Call ScriptManager.RegisterPostBackControl() and pass in the button in question. This is the best solution for controls that are added dynamically, such as those inside a repeating template.

-------------------------------------------------------

After I give up... The only solution is to add enableEventValidation="false" in the Page attribute.

Probably it is not the best solution because the event validation mechanism reduces the risk of unauthorized postback requests and callbacks. When the EnableEventValidation property is set to true, ASP.NET allows only the specific events that can be raised on the control during a postback request or callback. In this model, a control registers its events during rendering and then validates the events during postback or callback handling.

However after debugging I relies that It throw that error after I write into a session which I never write anything in the beginning. which cause the event validation not valid

So another solution is if EnableEventValidation is so important then
put it back EnableEventValidation = true then
in your Page_Load Event,
put
----------------------
Session["something"] = true; in your page load event.

This will create the cookie needed for the session variable to work, and therefore anything using a session will also work without throwing the error.

---------------------

This solution needed if there is no session ha s been initialize but when there is asynchronous postback, you put a session and EnableEventValidation is true

Monday, October 29, 2007

The Simplest Javascript to convert to hexadecimal in Javascript

function toHexa(d) {return d.toString(16);}

function toDec(h) {return parseInt(h,16);}