Как мне показать модальный диалог, который отслеживает задачу? - PullRequest
0 голосов
/ 31 марта 2019

Мне понятно, есть ли у меня кнопка, которая вызывает событие, но в приведенном ниже случае я хочу открыть диалоговое окно.Код ниже беспорядок, я не знаю, как это сделать правильно.Я думаю, что 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 Ответ

1 голос
/ 31 марта 2019

Здесь есть две точки:

  1. Конструктор вашей формы не может иметь модификатор async.В качестве альтернативы вы можете использовать Load событие .

  2. (Необязательно) Вам не нужно передавать экземпляр "родительской" формыв конструктор, вы можете получить его непосредственно из свойства Owner, если вы используете ShowDialog(this) вместо ShowDialog().

Кроме того, не забудьте утилизировать любую диалоговую форму после того, как выс этим покончено.Предпочтительно, оберните его использование в using блок .

Вот как я бы это сделал;В форме 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 вы можете использовать любой тип, наиболее подходящий для вашей ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...