c# - 如何显示跟踪任务的模式对话框?
问题描述
如果我有一个触发事件的按钮,我很清楚,但在下面的情况下,我想弹出一个对话框。下面的代码是一团糟,我不知道该怎么做。我认为 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;
}
}
解决方案
这里有两点:
表单的构造函数不能有
async
修饰符。作为替代方案,您可以改用该Load
事件。(可选)您不需要将“父”表单的实例传递给构造函数,
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
,您可以使用最适合您的情况的任何类型。
推荐阅读
- c - 管道之间的迭代通信
- javascript - 为什么我在浏览器上调整大小时页面会滚动?
- gitlab - 如何确保使用 GitLab CI 更改了文件?
- r - 我打开我的 R 控制台并收到此消息 - '错误:找不到函数“install.packages”'。我该如何解决?
- linux - 如何让 GDB 将我手工制作的可运行 ELF 文件识别为可执行文件?
- npm - 错误:子编译失败:找不到入口模块:错误:无法解析[文件路径]
- python - 如何在不使用拆分方法的情况下找到字符串中最长的单词
- python-3.x - DRF Serializer 在执行 serializer.data 时返回空字典
- nginx - Nginx 和 certbot 的 ERR_SSL_PROTOCOL_ERROR
- postgresql - MacOS 上本地 postgres 实例中的符号链接问题