Intereting Posts

Использование WPF ProgressBar при использовании Async / Await

У меня очень простая задача, которая загружает некоторые данные:

async Task<List> GetInvoices() { var invoices = await Task.Run(() => db.Invoices.AsNoTracking().ToList()); return invoices; } 

Какой был бы лучший способ использовать это с помощью progressbar? Мне не нужно загружать процент (хотя это было бы полезно), мне просто нужно показать / скрыть панель прогресса при запуске и окончании загрузки данных. Есть ли способ создать законченный или законченный метод?

Я очень новичок в async / жду, так что детские перчатки, пожалуйста!

Предполагая, что GetInvoices в каком-то обработчике событий UI, и есть некоторый контроль выполнения, который называется ProgressBar , это очень просто:

 private async void OnButton1Click(..) { ProgressBar.IsIndeterminate = true; var result = await GetInvoices(); ProgressBar.IsIndeterminate = false; // Maybe hide it, too // TODO: Do stuff with result } 

Если вы хотите показать фактический прогресс, посмотрите Progress и IProgress .

У вас уже есть то, что вам нужно. Чтобы проиллюстрировать здесь простой пример с задачами и использованием ждут, и ContinueWith.

 using System; using System.Threading.Tasks; using System.Diagnostics; public class Program { public static void Main() { Task t = new Program().TestTasks(); Console.WriteLine("hello"); t.Wait(); } public async Task TestTasks() { Stopwatch watch = Stopwatch.StartNew(); Console.WriteLine("1." + watch.ElapsedMilliseconds); // await task int res = await TestAsync(); Console.WriteLine("2." + watch.ElapsedMilliseconds + " " + res); // save task and wait on it Task t = TestAsync(); t.ContinueWith((r) => { Console.WriteLine("4." + watch.ElapsedMilliseconds + " " + r.Result); }); Console.WriteLine("3." + watch.ElapsedMilliseconds); t.Wait(); } public static async Task TestAsync() { await Task.Delay(TimeSpan.FromSeconds(2)); return 42; } } 

Это печатает:

 1.0 hello 2.2009 42 3.2009 4.4013 42 

Обратите внимание на то, как ожидание покидает метод и печатает «привет» в методе «Основные», а после (около) двух секунд в методе TestTasks. С другой стороны, если мы не ожидаем, как показывает второй вызов TestAsync, 3. печатается немедленно, и через 2 секунды печатается 4..

Имея это в виду, вы можете просто вызвать свой метод GetInvoices с GetInvoices так как вы возвращаете задачу.

 // Set state of progressbar to indeterminate List result = await GetInvoices(); // Set state of progressbar to nothing 

Вы можете сделать что-то вроде:

 var task = Task.Run(() => db.Invoices.AsNoTracking().ToList()); //show progress task.ContinueWith(...CLOSE PROGRESS BAR...); 

На практике вы используете конструкцию Task.ContinueWith, чтобы поймать завершение задачи и скрыть индикатор выполнения, который вы показали ранее.

Примечание: имейте в виду, что для работы с элементом пользовательского интерфейса из другого streamа требуется вызов Invoke() , поскольку этот вызов перенаправляет фактическую инкакацию на основной stream, который является единственным streamом, поскольку элементы управления пользовательским интерфейсом могут работать в windowsх.