C# 在处理过程中启用响应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) {

当我点击一个按钮时,我在winform中有一个很长的处理过程;也就是说,我正在加载很多文件并处理它们。在处理期间,我的GUI被冻结且无响应,这是一个问题,因为处理可能需要10分钟以上的时间。有没有一种方法可以将代码放入某种气泡或其他东西中,以便在处理文件时使用GUI?甚至可以添加“取消”按钮

编辑:勒内的解决方案有效,这里还有我想要的
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,还有很多问题需要解决。