首页 > 解决方案 > 如何显示跟踪任务的模式对话框?

问题描述

如果我有一个触发事件的按钮,我很清楚,但在下面的情况下,我想弹出一个对话框。下面的代码是一团糟,我不知道该怎么做。我认为 async/await 是其中的一部分,但我不清楚这种情况。

class TaskObject : Form
{
    public void MyFunc()
    { 
      MyDialog d = new MyDialog(this);
      d.ShowDialog(); // I don't want any other interaction except this dialog's controls
    }
    internal async Task<bool> LongFunction()
    {
      // ...
      return true;
    }

}
class MyDialog : Form
{
  Task<bool> task;
  public async MyDialog(TaskObject o)
  {
     task = new Task<bool>(o.LongFunction);
     await task;
  }
  void when_LongFunction_does_something_interesting()
  {
    this.MyTextBox.Text = "Something interesting";
  }
  void when_task_completes()
  {
     this.CancelButton.Visible = false;
     this.CloseButton.Visible = true;
  }
}

标签: c#winformsasync-await

解决方案


这里有两点:

  1. 表单的构造函数不能有async修饰符。作为替代方案,您可以改用该Load事件

  2. (可选)您不需要将“父”表单的实例传递给构造函数,Owner如果您使用ShowDialog(this)而不是ShowDialog().

另外,请记住在完成后处理任何对话框表单。最好将它的用法包装在一个usingblock中。

这是我的做法;在TaskObject表格中:

internal async Task<bool> LongFunction()
{
    // Do some magic.
    // await ...

    return true;
}

public void MyFunc()
{
    using (MyDialog d = new MyDialog())
    {
        d.ShowDialog(this);
    }
}

MyDialog表格中:

private async void MyDialog_Load(object sender, EventArgs e)
{
    TaskObject owner = this.Owner as TaskObject;
    await owner.LongFunction();
    when_task_completes();
}

如果您还想跟踪 的进度LongFunction,您可以为其添加一个Progress<T>参数并像这样使用它:

internal async Task<bool> LongFunction(IProgress<string> progress)
{
    // Do some magic.
    progress.Report("Something interesting");
    // await ...
    // More magic.
    return true;
}

然后你可以做这样的事情:

private async void MyDialog_Load(object sender, EventArgs e)
{
    TaskObject owner = this.Owner as TaskObject;

    var progress = new Progress<string>(s => when_LongFunction_does_something_interesting(s));
    await owner.LongFunction(progress);
    when_task_completes();
}

void when_LongFunction_does_something_interesting(string message)
{
    this.MyTextBox.Text = message;
}

请注意,我用作Progress<string>示例。代替string,您可以使用最适合您的情况的任何类型。


推荐阅读