using a System.Threading.Monitor
class will do the trick like:
private readonly object _userActivityLocker = new object();
private void btnSave_Click(object sender, EventArgs e)
{
new Thread(delegate()
{
if (System.Threading.Monitor.TryEnter(_userActivityLocker))
{
//note that any sub clicks will be ignored while we are here
try
{
//here it is safe to call the save and you can disable the btn
}
finally
{
System.Threading.Monitor.Exit(_userActivityLocker);
//re-enable the btn if you disable it.
}
}
}) { IsBackground = true }.Start();
}
To prove that changing the button to enable or disable state is not enough here a simple test:
Add a new form and add a button1 to it and inside the button1 click event handler write the following code:
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
Console.WriteLine("First Message");
Thread.Sleep(2000);
Console.WriteLine("second Message");
button1.Enabled = true;
}
and then build and run the application, double click on the button1 and the result int the output window will be:
First Message
second Message
First Message
second Message
so we have to make sure only one click is executed even when double click or so and that accomplished simply by using the System.Threading.Monitor
Update: Note that you can use a Task "if C# 4.0", a ThreadPool.QueueUserWorkItem or BackgroundWorker as a substitute of Thread.