C# 在处理过程中启用响应GUI
当我点击一个按钮时,我在winform中有一个很长的处理过程;也就是说,我正在加载很多文件并处理它们。在处理期间,我的GUI被冻结且无响应,这是一个问题,因为处理可能需要10分钟以上的时间。有没有一种方法可以将代码放入某种气泡或其他东西中,以便在处理文件时使用GUI?甚至可以添加“取消”按钮 编辑:勒内的解决方案有效,这里还有我想要的C# 在处理过程中启用响应GUI,c#,winforms,async-await,C#,Winforms,Async Await,当我点击一个按钮时,我在winform中有一个很长的处理过程;也就是说,我正在加载很多文件并处理它们。在处理期间,我的GUI被冻结且无响应,这是一个问题,因为处理可能需要10分钟以上的时间。有没有一种方法可以将代码放入某种气泡或其他东西中,以便在处理文件时使用GUI?甚至可以添加“取消”按钮 编辑:勒内的解决方案有效,这里还有我想要的progressbar控件: private async void button1_Click(object sender, EventArgs e) {
progressbar
控件:
private async void button1_Click(object sender, EventArgs e)
{
progressBar1.Maximum = ValueWithTOtalNumberOfIterations.Length;
IProgress<int> progress = new Progress<int>(value => { progressBar1.Value = value;});
await Task.Run(() =>
{
var tempCount = 0;
//long processing here
//after each iteration:
if (progress != null)
{
progress.Report((tempCount));
}
tempCount++;
}
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
progressBar1.Maximum=带总迭代次数的值。长度;
IProgress progress=new progress(值=>{progressBar1.value=value;});
等待任务。运行(()=>
{
var-tempCount=0;
//这里处理时间长
//每次迭代后:
如果(进度!=null)
{
进度报告((临时计数));
}
tempCount++;
}
}
您只需使按钮的单击处理程序异步
,并为长时间运行的操作启动一个任务
:
public async void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false; // disable button to not get called twice
await Task.Run(() =>
{
// process your files
}
button1.Enabled = true; // re-enable button
}
编译器将其转换为状态机。控制流在await
关键字处返回给调用方(UI)。当任务完成后,此方法的执行将恢复
要使用“取消”按钮,您可以使用或仅定义一个在处理文件时检查的标志,并在设置标志时返回(通过“取消”按钮的单击处理程序):
您只需使按钮的单击处理程序异步
,并为长时间运行的操作启动任务
:
public async void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false; // disable button to not get called twice
await Task.Run(() =>
{
// process your files
}
button1.Enabled = true; // re-enable button
}
编译器将其转换为状态机。控制流在await
关键字处返回给调用方(UI)。当任务完成后,此方法的执行将恢复
要使用“取消”按钮,您可以使用或仅定义一个在处理文件时检查的标志,并在设置标志时返回(通过“取消”按钮的单击处理程序):
查看async/await您可以使用BackgroundWorker。请参阅此链接-有关取消按钮操作,请使用CancelAsync方法。是的,有不同的方法可以实现此目的。您可能应该搜索async await(如果您使用的是net fw 4.5或更高版本),因为您已经正确标记了此项,然后进行尝试;)看看async/Wait,您可以使用BackgroundWorker。请参阅此链接-有关取消按钮操作,请使用CancelAsync方法。是的,有不同的方法可以实现此目的。您可能应该搜索async await(如果您使用的是net fw 4.5或更高版本),因为您已经正确标记了它,然后进行了尝试;)太好了,谢谢!但是现在我的处理代码中出现了一个错误,比如我的DialogResult=folder.ShowDialog()上的ThreadStateException代码>。表示在进行OLE调用之前,必须将当前线程设置为STA模式。我知道我不应该在这里问这个问题,但是你知道如何修复它吗?哦,你不应该在任务内部打开另一个对话框,因为它是在不同于ui的线程上执行的。啊,我明白了。启动处理的按钮首先打开FolderBrowser对话框以选择文件。然后我应该定位任务。在下面运行吗?是的,将Task.Run
放在所有GUI相关操作的下面就可以了。然而,由于类似的原因,新的错误也会弹出,因为我在按钮下方有一个文本框
,在处理每个单独的文件后显示确认消息。我是否应该在任务执行期间不使用任何与GUI相关的操作。在这种情况下,运行
,或者是否有方法仍然使用textbox`呢?您可以使用BeginInvoke()
或使用IProgress
将进度报告回ui线程。关于如何从不同的线程更新winforms ui,有很多内容。这太棒了,谢谢!但是现在我的处理代码中出现了一个错误,比如我的DialogResult=folder.ShowDialog()上的ThreadStateException代码>。表示在进行OLE调用之前,必须将当前线程设置为STA模式。我知道我不应该在这里问这个问题,但是你知道如何修复它吗?哦,你不应该在任务内部打开另一个对话框,因为它是在不同于ui的线程上执行的。啊,我明白了。启动处理的按钮首先打开FolderBrowser对话框以选择文件。然后我应该定位任务。在下面运行吗?是的,将Task.Run
放在所有GUI相关操作的下面就可以了。然而,由于类似的原因,新的错误也会弹出,因为我在按钮下方有一个文本框
,在处理每个单独的文件后显示确认消息。我是否应该在任务执行期间不使用任何与GUI相关的操作。在这种情况下,运行
,或者是否有方法仍然使用textbox`呢?您可以使用BeginInvoke()
或使用IProgress
将进度报告回ui线程。关于如何从不同的线程更新winforms ui,还有很多问题需要解决。