Хочу показать, как идут вычисления во внешней библиотеке.
Например, если у меня есть метод вычисления, и я хочу использовать его для 100000 значений в моем классе формы, я могу написать:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Caluculate(int i)
{
double pow = Math.Pow(i, i);
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Maximum = 100000;
progressBar1.Step = 1;
for(int j = 0; j < 100000; j++)
{
Caluculate(j);
progressBar1.PerformStep();
}
}
}
Я должен выполнять шаг после каждого расчета. Но что, если я выполню все 100000 вычислений внешним методом. Когда мне следует «выполнить шаг», если я не хочу, чтобы этот метод зависел от индикатора выполнения? Я могу, например, написать
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void CaluculateAll(System.Windows.Forms.ProgressBar progressBar)
{
progressBar.Maximum = 100000;
progressBar.Step = 1;
for(int j = 0; j < 100000; j++)
{
double pow = Math.Pow(j, j); //Calculation
progressBar.PerformStep();
}
}
private void button1_Click(object sender, EventArgs e)
{
CaluculateAll(progressBar1);
}
}
но я не хочу этого делать.
c#
winforms
progress-bar
Дмитрий
источник
источник
Ответы:
Я предлагаю вам взглянуть на BackgroundWorker . Если у вас есть такой большой цикл в WinForm, он будет заблокирован, и ваше приложение будет выглядеть так, как будто оно зависло.
смотреть на
BackgroundWorker.ReportProgress()
как сообщить о ходе выполнения в поток пользовательского интерфейса.Например:
источник
BackgroundWorker
добавляется через дизайнер и настраивается там. Но да, его нужно будет настроить, чтобыWorkerReportsProgress
установить значениеtrue
.RunWorkerCompleted
обработчике событий, если вашDoWork
обработчик этого не делает ..Начиная с .NET 4.5, вы можете использовать комбинацию async и await with Progress для отправки обновлений в поток пользовательского интерфейса:
Задачи в настоящее время являются предпочтительным способом реализации того, что
BackgroundWorker
делает.источник
await DoWorkAsync(progress);
? Это сделано специально, так как это не приведет к запуску дополнительного потока. Функция продолжится только в том случае, еслиDoWorkAsync
вызовет ее собственный,await
например, для ожидания операции ввода-выводаbutton1_Click
. На это время основной поток пользовательского интерфейса заблокирован. Если наDoWorkAsync
самом деле это не асинхронный режим, а просто много синхронных операторов, вы ничего не получите.Step
доступно только в индикаторе выполнения WinForms и здесь не нужно, но оно присутствовало в примере кода вопроса (помеченные winforms), так что, возможно, это могло остаться.Привет, есть полезный учебник по жемчугу Dot Net: http://www.dotnetperls.com/progressbar
По соглашению с Питером, вам нужно использовать некоторое количество потоков, иначе программа просто зависнет, что несколько нарушит цель.
Пример, в котором используются ProgressBar и BackgroundWorker: C #
источник
Есть
Task
, бесполезноBackgroundWorker
,Task
проще. например:ProgressDialog.cs:
Готово! Затем вы можете повторно использовать ProgressDialog где угодно:
источник