#c# #forms #backgroundworker
#c# #формы #backgroundworker
Вопрос:
В настоящее время я пытаюсь обновить индикатор выполнения, если фоновый рабочий что-то сообщает, вот мой код
Form1.cs
namespace YTD
{
public partial class Form1 : Form
{
private Main app;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int n;
bool isNumeric = int.TryParse(numberBox.Text, out n);
if (!String.IsNullOrWhiteSpace(emailBox.Text) amp;amp; !String.IsNullOrWhiteSpace(passBox.Text) amp;amp; !String.IsNullOrWhiteSpace(numberBox.Text) amp;amp; isNumeric)
{
this.app = new Main(emailBox.Text, passBox.Text, n, logBox, statusBar, backgroundWorker1);
this.app.startMule();
}
else
{
MessageBox.Show("Please fill out all the form fields", "MuleMaker error");
}
}
}
}
И мой Main.cs
namespace YTD.classes
{
public class Main
{
private String email;
private String password;
private int number;
private RichTextBox logBox;
private ProgressBar statusBar;
private BackgroundWorker threadWorker;
public Main(String email, String password, int number, RichTextBox logBox, ProgressBar statusBar, BackgroundWorker threadWorker)
{
// Define some variables
this.email = email;
this.password = password;
this.number = number;
this.logBox = logBox;
this.statusBar = statusBar;
this.threadWorker = threadWorker;
}
public void startMule()
{
// Set progressbar 100% value
statusBar.Maximum = this.number;
if (!threadWorker.IsBusy)
{
threadWorker.RunWorkerAsync();
}
}
private void threadWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 10; i )
{
// Perform a time consuming operation and report progress.
MessageBox.Show("ye");
System.Threading.Thread.Sleep(500);
threadWorker.ReportProgress(i * 10);
}
}
private void threadWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
statusBar.Increment(1);
}
}
}
В настоящее время я не получаю ошибок, но значение индикатора выполнения не изменяется.
Без фонового рабочего я могу нормально обновлять индикатор выполнения, но не при выполнении дорогостоящего действия.
Комментарии:
1. Вам нужно сделать
backgroundWorker1.WorkerReportsProgress = true;
2. Я сделал это в среде IDE
3.
threadWorker_DoWork
выполняется ли?4. Я попробовал несколько тестовых кодов, и никто не выполняется, поэтому похоже, что нет: s
5. Я был занят и пропустил это: o)) Я собирался сообщить, что в нем не запущено, у вас не подключено
worker.DoWork
событие
Ответ №1:
Ваш опубликованный код не отображается, если вы зарегистрировали свои функции в событиях BackgroundWorker.
Недостаточно создать новый BackgrounWorker. Вот пример:
public Class Main
{
public Main( ... )
{
BackgroundWorker worker = new BackgroundWorker()
worker.WorkerReportsProgress = true;
// Register to BackgroundWorker-Events
worker.DoWork = threadWorker_DoWork;
worker.ProgressChanged = threadWorker_ProgressChanged;
}
}
кроме того, вы должны указать вашей панели прогресса на повторный запуск.
private void threadWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
statusBar.Increment(1);
statusBar.Invalidate(true);
}
по крайней мере, вы можете захотеть использовать значение, которое вы установили для вызова ReportProgress(i * 10)
.
private void threadWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
statusBar.Value = e.ProgressPercentage;
statusBar.Invalidate(true);
}
Комментарии:
1. Спасибо, кстати, один быстрый вопрос, что я могу использовать.StatusBar или просто StatusBar?
2. Я думаю, вы могли бы использовать это или нет, как вам нравится. Но вы должны решить, если или если нет, и сохранить его для всего проекта. Поскольку в основном ясно, что вы хотите использовать переменную локальной области, я решил НЕ использовать ее.
3. Хорошо и последнее, когда я запускаю код, все работает. если я снова нажму кнопку, то кажется, что фоновый рабочий вызывается дважды, я выводю процент процесса. Сначала он показывает правильно: 1, 2, 3, 4… 10 но затем, если я снова нажму : 1, 1, 2, 2, 3, 3 … 10, 10
4. в вашем событии щелчка:
this.app = new Main( ... )
. Похоже, вы всегда используете НОВЫЙ! BackgroundWorker и передайте его вашему основному методу. Вы должны проверить, действительно ли вам нужно создавать экземпляр нового класса для каждого щелчка, или вы можете сгенерировать его в своем конструктореForm1() { ... }
. Если вы всегда используете один и тот же объект вашего основного классаstartMule()
, он будет делать то, для чего он создан: запускайте BackgroundWorker только ОДИН РАЗ (для каждого экземпляраMain
)!5. Да, переместил некоторый код, и теперь все идет хорошо. Как мне использовать переменные, переданные в threadWorker_ProgressChanged ? Я имею в виду, что я должен передать что-то здесь this.ThreadWorker. ReportProgress(i); но как мне получить к нему доступ? Я попробовал e.ProgressPercentage. toString() но не уверен, правильно ли это