I had a situation on a website I was working on, where users enter their name and email address on a javascript modal dialog, and an email with an attachment is sent to them. The log was showing multiple attempts by the same people. the site administrator presumed that the email send operation was failing and that the user's were attempting it multiple times.
What it actually turned out to be, was that the code that generates the email attachment, then builds and queues the email, was taking about four seconds to complete. That, combined with the postback, was pushing five seconds. the user simply thought they hadn't sufficiently clicked the button, so they were clicking it again, and again befofe the form could close.
I needed a way to disable the submit button before posting back, but standard client-side javascript to disable the button was preventing the Postback from occurring. Then I found this...
http://www.codeproject.com/KB/aspnet/ASPNET_Buttons.aspx
The gist of it is you need to add an onclick attribute to the button using the ClientScript.GetPostBackEventReference functionality described here...
http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.getpostbackeventreference.aspx
And here is what it looks like in a CS page's AttachChildControls method (3rd line is the trick)...
_continueButton = CSControlUtility.Instance().FindControl(this, ContinueButtonID) as Button;
_continueButton.Click += Button_Click;
_continueButton.Attributes.Add("onclick",
_continueButton.Page.ClientScript.GetPostBackEventReference(_continueButton, "")
+ "; this.value='Sending Email...'; this.disabled = true;");
See following images to see the before click and after click results.
By the way, the form this was used on has server-side validation on the fields. When the user clicks the button with invalid data in the fields, the button says, "Sending Email..." for a flash then the form reloads with the invalid entry messages and a newly enabled button, so everything is fine there too.