C # atualização da interface do usuário na tarefa

Eu sou novo no C# Task e threading.

Eu tenho um código como abaixo: –

 public void UpdateSales(object sender, EventArgs args) { Task.Run(() => { // Some code Create Collection ... // Some code with business logic .. // Below code is to update UI // is it safe to update UI like below saleDataGrid.Dispatcher.Invoke((Action) (() => { saleDataGrid.ItemsSource = currentCollection; saleDataGrid.Items.Refresh(); })); }); } 

Não tenho certeza se esse código está correto ou não. Eu acho que em qualquer caso o impasse pode ocorrer?

Você pode por favor apontar como posso atualizar a interface do usuário da tarefa? Eu não estou usando async/await UpdateSales porque UpdateSales é manipulador de events da biblioteca de terceiros.

Supondo que UpdateSales seja chamado no thread da interface do usuário, uma solução mais limpa seria esta:

 public async void UpdateSales() { var collection = await Task.Run(() => { // Some code Create Collection ... // Some code with business logic .. return currentCollection; }); saleDataGrid.ItemsSource = collection; saleDataGrid.Items.Refresh(); } 

Como descrevo no meu blog, o await será retomado automaticamente em um contexto capturado (neste caso, o contexto da interface do usuário). Eu prefiro muito mais usar o contexto implícito do await vez do Dispatcher diretamente: o código é mais curto e mais portátil.

Como você sabe, o Task.Run será executado em um thread de threadpool.

Você pode então usar um ContinueWith que será executado na conclusão dessa tarefa – e se você escolher uma das substituições que lhe permitem especificar um TaskScheduler, então você pode usar TaskScheduler.FromCurrentSynchronizationContext (), que usará o contexto de synchronization que você digitou Método ligado – se for um segmento de interface do usuário (por exemplo, você está em um manipulador de events para um evento de interface do usuário), o contexto de synchronization será o do segmento de interface do usuário.

Então, seu código será parecido com isto:

 Task.Run(() => { ...code to create collection etc... } ) .ContinueWith(() => { saleDataGrid.ItemsSource = currentCollection; } , TaskScheduler.FromCurrentSynchronizationContext() );