异步显示对话框 [英] Async ShowDialog

查看:28
本文介绍了异步显示对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 async/await 从数据库中异步加载我的数据,在加载过程中,我想弹出一个加载表单,它只是一个带有运行进度条的简单表单,以指示有一个正在运行的进程.加载数据后,对话框将自动关闭.我怎样才能做到这一点?以下是我当前的代码:

I'm using async/await to asynchronously load my data from database and during the loading process, I want to popup a loading form, it's just a simple form with running progress bar to indicate that there's a running process. After data has been loaded, the dialog will automatically be closed. How can I achieve that ? Below is my current code:

 protected async void LoadData() 
    {
       ProgressForm _progress = new ProgressForm();  
       _progress.ShowDialog()  // not working
       var data = await GetData();          
       _progress.Close();
    }

更新:

我设法通过更改代码使其工作:

I managed to get it working by changing the code:

 protected async void LoadData() 
        {
           ProgressForm _progress = new ProgressForm();  
           _progress.BeginInvoke(new System.Action(()=>_progress.ShowDialog()));
           var data = await GetData();          
           _progress.Close();
        }

这是正确的方法还是有更好的方法?

Is this the correct way or there's any better ways ?

感谢您的帮助.

推荐答案

使用 Task.Yield 很容易实现,如下所示(WinForms,为了简单起见,没有异常处理).重要的是要了解执行流程如何在此处跳转到新的嵌套消息循环(模态对话框的),然后返回原始消息循环(这就是 await progressFormTask 的用途):

It's easy to implement with Task.Yield, like below (WinForms, no exception handling for simplicity). It's important to understand how the execution flow jumps over to a new nested message loop here (that of the modal dialog) and then goes back to the original message loop (that's what await progressFormTask is for):

namespace WinFormsApp
{
  internal static class DialogExt
  {
    public static async Task<DialogResult> ShowDialogAsync(this Form @this)
    {
      await Task.Yield();
      if (@this.IsDisposed)
        return DialogResult.Cancel;
      return @this.ShowDialog();
    }
  }

  public partial class MainForm : Form
  {
    public MainForm()
    {
      InitializeComponent();
    }

    async Task<int> LoadDataAsync()
    {
      await Task.Delay(2000);
      return 42;
    }

    private async void button1_Click(object sender, EventArgs e)
    {
      var progressForm = new Form() { 
        Width = 300, Height = 100, Text = "Please wait... " };

      object data;
      var progressFormTask = progressForm.ShowDialogAsync();
      try 
      {
        data = await LoadDataAsync();
      }
      finally 
      {
        progressForm.Close();
        await progressFormTask;
      }

      // we got the data and the progress dialog is closed here
      MessageBox.Show(data.ToString());
    }
  }
}

这篇关于异步显示对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆