我有一个带有表单窗口的C#应用程序,上面有一个按钮,我会调用myButton
。我附上了一个事件myButton_Click
。我想要做的是在myButton_Click
方法中的操作正在运行时禁用按钮并且不允许任何用户界面与按钮。
目前我从myButton_Click
方法中启动了另一个可执行文件,就像我说的那样,在其他应用程序运行时我不希望任何用户交互。我遇到的问题是,即使按钮被myButton.Enabled == false;
禁用,如果我关闭从“myButton_Click
”内启动的正在运行的应用程序,我在禁用按钮上多次单击,当我点击之前禁用的按钮时,方法“myButton_Click
”会被多次调用。
简而言之,我希望有一种方法可以确保在我禁用的按钮上运行外部应用程序时不会存储/累积任何操作/按钮点击。
E.g。
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
}
由于
答案 0 :(得分:3)
外部EXE正在阻止UI线程,并且它正在排队这些点击事件。正确的解决方案是使用这样的后台工作者:
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();
}
答案 1 :(得分:3)
我认为使用async / await可以提供更清晰的解决方案
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;
}
答案 2 :(得分:0)
我很惊讶你甚至遇到了这个问题。可能是Windows消息没有足够快地禁用按钮。您可以尝试在DoEvents()
myButton.Enabled = false;
指令