Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 等待任务中的等待任务-代码的其余部分何时执行?_C#_Asynchronous_Task - Fatal编程技术网

C# 等待任务中的等待任务-代码的其余部分何时执行?

C# 等待任务中的等待任务-代码的其余部分何时执行?,c#,asynchronous,task,C#,Asynchronous,Task,考虑主窗体加载事件的这一部分: private async void MainForm_Load(object sender, EventArgs e) { var ServerConfigFile = new ClientConfigFile(Environment.CurrentDirectory); ServerConfigFile.GenerateConfigFile(); var taskCheck = Task.Run(() =&g

考虑主窗体加载事件的这一部分:

 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
完成其所有代码的运行(包括最后注释的控件更改)?我的推理是,它启动一个
任务
,其中包含
CheckUpdate
,然后
等待
,将控制权返回到
主窗体
CheckUpdate
运行一个
任务,其中包含
GetServerConfig
函数,
等待
,将控制权传递回
MainForm\u Load
,但由于它仍在等待
CheckUpdate
完成,因此它不会继续执行
lblUpdateMessage.Text=“Finished…”行。还是我弄错了

Tl;dr在显示
Finished
之前,此代码是否确实等待所有
CheckUpdate
完成

在显示Finished之前,该代码是否实际等待所有CheckUpdate完成

否,因为
CheckUpdate
是一种
async void
方法

您可以将其设置为
async Task
,它将正确地等待
CheckUpdate
完成:

private async Task CheckUpdate()
但是,看看您的
CheckUpdate
函数,它似乎不需要在后台线程上运行。它更新UI控件,在后台线程上运行一些东西,然后更新UI控件。它显然是UI层的一部分,正如Servy指出的那样,跳转到后台线程(在
MainForm\u Load
中运行
Task.Run
)只是跳回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
),从而消除对
任务的任何需要。运行

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

有没有一个原因让你不能试着去看?为什么你在后台线程中运行一个方法只是为了让它安排在UI线程或其他后台线程中运行?只需在UI线程上运行它。@Janushoff是的,确实如此。该方法没有执行任何长时间运行的非UI工作,它只是执行UI工作并安排非UI工作在另一个线程中运行。不,假设它实际上是一个长时间运行的非UI操作,情况似乎就是这样。@Janushoff您的代码没有说它失败。它询问它是否会失败。如果你知道它失败了,那么显然你已经知道你问题的答案了。