2017-02-16 56 views
-2

考虑Load事件,这部分的主要形式有:await任务里面等待的任务 - 其他代码何时执行?

private async void MainForm_Load(object sender, EventArgs e) 
{ 
     var ServerConfigFile = new ClientConfigFile(Environment.CurrentDirectory); 
     ServerConfigFile.GenerateConfigFile(); 
     var taskCheck = Task.Run(() => CheckUpdate()); 
     await taskCheck; 
     lblUpdateMessage.Text = "Finished..."; 
     //more code here 
} 

而且CheckUpdate函数本身:

private async void CheckUpdate() 
{ 
     var connection = new ServerConnection(this); 

     Helper.CrossThreadInvoke(lblFileDownload,() => lblFileDownload.Text = "Downloading"); 

     Helper.CrossThreadInvoke(lblFileDownload,() => lblFileDownload.Text = "Done"); 
     var taskConfig = Task.Run(() => connection.GetServerConfig()); 
     await taskConfig; 
     ///some unrelated control changes here 
} 

此代码是否正确地等待CheckUpdate运行完毕,所有的代码(包括评论控制最后的变化)?我的推理是它开始TaskCheckUpdate它和awaits,返回控制MainFormCheckUpdate运行一个TaskGetServerConfig函数在它,awaits,传递控制回到MainForm_Load,但由于它仍然等待CheckUpdate完成,它不会继续到lblUpdateMessage.Text = "Finished...";行。或者我错了?

文艺青年最爱的此代码是否actaully等待所有的CheckUpdate以显示Finished前完成?

+1

是否有一个原因,你不能只是尝试一下,看看? –

+0

我试图和它失败 - 试图了解为什么它不工作。您是否有理由在没有任何实际建议的情况下评论如何处理它或如何改进帖子? – Janushoff

+2

为什么在后台线程中只运行一个方法让它安排工作在UI线程或其他后台线程中运行?只需在UI线程上运行它。 – Servy

回答

1

此代码在显示Finished之前是否等待所有CheckUpdate完成?

不,因为CheckUpdateasync void方法。

你可以把它async Task,这将适当地等待CheckUpdate完成:

private async Task CheckUpdate() 

然而,看着你CheckUpdate功能,它似乎并不需要在后台线程上运行。它更新UI控件,在后台线程上运行某些内容,然后更新UI控件。它显然是UI层的一部分,正如Servy指出的那样 - 跳转到后台线程(Task.RunMainForm_Load)只是为了跳回UI线程(Helper.CrossThreadInvoke)没有意义。

因此,消除这些不必要的线程跳转:

private async void MainForm_Load(object sender, EventArgs e) 
{ 
    var ServerConfigFile = new ClientConfigFile(Environment.CurrentDirectory); 
    ServerConfigFile.GenerateConfigFile(); 
    await CheckUpdateAsync(); 
    lblUpdateMessage.Text = "Finished..."; 
} 

private async Task CheckUpdateAsync() 
{ 
    var connection = new ServerConnection(this); 
    lblFileDownload.Text = "Downloading"; 
    lblFileDownload.Text = "Done"; 
    await Task.Run(() => connection.GetServerConfig()); 
    // some unrelated control changes here 
} 

最后,EJoshuaS指出,ServerConnection.GetServerConfig肯定听起来像一个I/O的操作。你可以把这些电话自然异步(例如,使用HttpClient),为Task.Run去除任何需要在所有:

private async Task CheckUpdateAsync() 
{ 
    var connection = new ServerConnection(this); 
    lblFileDownload.Text = "Downloading"; 
    lblFileDownload.Text = "Done"; 
    await connection.GetServerConfigAsync(); 
    // some unrelated control changes here 
}