如何显示跟踪任务的模式对话框?

时间:2019-03-30 23:08:20

标签: c# winforms 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;
  }
}

1 个答案:

答案 0 :(得分:1)

这里有两点:

  1. 表单的构造函数不能具有async修饰符。另外,您也可以使用Load event

  2. (可选),您无需将“父”表单的实例传递给构造函数,如果改为使用Owner,则可以直接从ShowDialog(this)属性获取它的ShowDialog()

此外,完成处理后,请记住要丢弃任何对话框形式。最好将其用法包装在using block中。

这就是我要怎么做;以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