I have a C# application with a form window that has a button on it, I'll call myButton
. I have an event attached to it, myButton_Click
. What I want to do is disable the button and not allow any user interface with the button while the actions within the myButton_Click
method are running.
Currently I launch another executable from within the myButton_Click
method and like I said I do NOT want any user interaction while the other application is running. The problem I am running into is that even though the button is disabled, by myButton.Enabled == false;
, if I click multiple times on the disabled button once I close the running application that was launched from within ' myButton_Click
', the method ' myButton_Click
' gets recalled as many times as I clicked on the disabled button previously.
In short I would like a way to make sure that no actions/button clicks are stored/accumulated while the outside application is running on the button that I disabled.
Eg
private void myButton_Click(object sender, EventArgs e)
{
myButton.Enabled = false;
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "someapplication.EXE";
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch{// Log error.
}
myButton.Enabled = true;// turn the button back on
}
Thanks
The UI thread is being blocked by your external EXE and it's queuing up those click events. The proper solution is to use a background worker like this:
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (doWorkSender, doWorkArgs) =>
{
// You will want to call your external app here...
Thread.Sleep(5000);
};
worker.RunWorkerCompleted += (completedSender, completedArgs) =>
{
button1.Enabled = true;
};
worker.RunWorkerAsync();
}
I think using async/await can give a cleaner solution
async private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
await RunProcessAsync("notepad.exe");
button1.Enabled = true;
}
public Task RunProcessAsync(string processName)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = processName;
var proc = Process.Start(startInfo);
proc.EnableRaisingEvents = true;
proc.Exited += (s,e) => tcs.TrySetResult(null);
return tcs.Task;
}
I'm surprised that you're even getting that problem. It could possibly be that the windows message is not disabling the button quick enough. You could try putting a DoEvents()
instruction after myButton.Enabled = false;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.