在 Windows 窗体加载事件中使用异步等待加载其他数据控件?

fdk*_*fsf 1 c# asynchronous winforms visual-studio-2015

我们有一个ParentForm打开的 Windows 窗体ChildForm。类似于以下内容:

var form = new ChildForm(parm1, parm2, parm3, parm4);
form.StartPosition = FormStartPosition.CenterParent;
form.ShowDialog();
Run Code Online (Sandbox Code Playgroud)

的构造函数ChildForm如下所示:

public ChildForm(string Parm1, string Parm2, string Parm3, string Parm4)
{
    InitializeComponent();

    FillThisComboBox();
    FillThisOtherComboBox();
    BindAnotherCombobox();
    BindGridview();
    FillCheckBoxList();
    FillAnotherCheckBoxList();
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,ChildForm加载需要一段时间,因为它在实际绘制表单之前运行所有这些方法。

我想使用所有这些方法来执行所有这些方法,async await以便在所有 ekse 运行时绘制 Form,并且我尝试了类似以下内容,但我继续收到构建错误:

private async void ChildForm_Load(object sender, EventArgs e)
{
    await PrepareControls();
}
private async Task PrepareControls()
{
    FillThisComboBox();
    FillThisOtherComboBox();
    BindAnotherCombobox();
    BindGridview();
    FillCheckBoxList();
    FillAnotherCheckBoxList();
}
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏。谢谢。

Joh*_*ers 5

Async/Await 有一些规则如下:

  1. 任何标记为 async 的方法必须返回一个空值、任务或某物的任务。
  2. 异步事件处理程序返回 void 以匹配 EventHanlder 定义/签名
  3. 使其他方法异步通常遵循以下模式:

    public async Task<ofSomething> DoSomething(){
         //entry here is on the caller's thread.
         var x =await Task<ofSomething>.Run(()=>{
             //this code will be run independent of calling thread here
             return GetSomething();
          }
         //at this point you are back on the caller's thread.
         //the task.result is returned.
         return x;
    } 
    
    Run Code Online (Sandbox Code Playgroud)

每个异步方法都有一个或多个“等待”一个值的语句。变量 x 是“关闭返回 OfSomeThing 类型的 GetSomething 结果的任务。

要在返回 void 的 eventhanlder 中使用上面的代码...正如您已经知道的那样,您必须输入 async 关键字

public async void ClickEventHandler(object sender, EvantArgs e){
    var x = await DoSomething();
    //var x now has the ofSomething object on the gui thread here.
}
Run Code Online (Sandbox Code Playgroud)

请注意,单击处理程序返回 void 以满足单击处理程序的委托签名,但它调用不返回 void 的异步方法。

并发、错误处理和取消都很重要,所以也要研究这些。欢迎来到异步世界。异步世界让事情变得更容易了。

警告总是这样做

2012 年,Stephen Cleary 写了一篇关于Configure.Await(false) 的文章

我随后在一个真实的应用程序中学会了确保始终做到这一点。它大大加快了速度并避免了其他问题。

  • Async/Await 让它看起来很容易,但是等到你在 UI 代码中遇到第一个死锁,然后你哭着跑向 [异步的 Jon Skeet](https://blog.stephencleary.com/2014/04/a- tour-of-task-part-0-overview.html)然后你花了三天时间阅读并意识到:不,这并不是更容易,只是更容易打字。 (2认同)