2017-02-16 3 views
-2

Рассмотрим эту часть события нагрузки для основной формы:Ожидание Задача внутри ожидаемой задачи - когда выполняется оставшаяся часть кода?

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, чтобы завершить работу всех его кода (включая комментируемого контроль изменений в конце)? Мое рассуждение состоит в том, что он начинает Task с CheckUpdate в нем, и awaits, возвращая управление на MainForm.забрасывает Task с GetServerConfig в положение awaits, после чего возвращается на MainForm_Load, но так как он ждет CheckUpdate, он не переходит на lblUpdateMessage.Text = "Finished...";. Или я ошибаюсь?

Tl; др ли этот код Actaully ждет все CheckUpdate закончить перед отображением Finished?

+1

Есть причина, вы не можете просто попробовать и посмотреть? –

+0

Я пытаюсь, и он терпит неудачу - пытаясь понять, почему это не работает. Есть ли причина, по которой вы прокомментировали без каких-либо фактических советов о том, как справиться с ней или как улучшить эту должность? – Janushoff

+2

Почему вы используете метод в фоновом потоке только для того, чтобы он планировал работу для запуска в потоке пользовательского интерфейса или в другом фоновом потоке? Просто запустите его в потоке пользовательского интерфейса. – Servy

ответ

1

Выполняет ли этот код действие полностью для проверки CheckUpdate перед отображением Готово?

Нет, поскольку CheckUpdate - это метод async void.

Вы могли бы сделать его async Task, что бы правильно ждать CheckUpdate для завершения:

private async Task CheckUpdate() 

Однако, глядя на вашу CheckUpdate функцию, она, кажется, не нужно запускать в фоновом потоке. Он обновляет элементы пользовательского интерфейса, запускает что-то в фоновом потоке и обновляет элементы пользовательского интерфейса. Это явно часть слоя пользовательского интерфейса, и, как указал Servy, нет смысла прыгать в фоновый поток (Task.Run в MainForm_Load), чтобы вернуться к потоку пользовательского интерфейса (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 
} 
Смежные вопросы