Думайте, что лучше стать более конкретным, а не общим с подобными вопросами.
К Вашему вопросу, я не думаю, что он испорчен, но Вы правы, что он не может обратиться к некоторым. Однако, как только люди получают его, поскольку в понимают его, тогда они могут прибыть для использования его больше. Это - конечно, лучшая вещь должным быть помнить меньше паролей, поскольку каждый заканчивает создание их более слабый, чем они должны быть.
Некоторым это может не понравиться, но я этим занимаюсь:
private void StartBackgroundWork() {
if (Application.RenderWithVisualStyles)
progressBar.Style = ProgressBarStyle.Marquee;
else {
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.Maximum = 100;
progressBar.Value = 0;
timer.Enabled = true;
}
backgroundWorker.RunWorkerAsync();
}
private void timer_Tick(object sender, EventArgs e) {
if (progressBar.Value < progressBar.Maximum)
progressBar.Increment(5);
else
progressBar.Value = progressBar.Minimum;
}
Для стиля Marquee требуется, чтобы были включены VisualStyles, но он непрерывно прокручивается сам по себе, не требуя обновления. Я использую это для операций с базой данных, которые не сообщают об их ходе.
Когда вы выполняете операции в фоновом потоке и хотите обновить пользовательский интерфейс, вы не можете вызывать или устанавливать что-либо из фонового потока. В случае WPF вам понадобится Dispatcher.BeginInvoke, а в случае WinForms вам понадобится метод Invoke.
WPF:
// assuming "this" is the window containing your progress bar..
// following code runs in background worker thread...
for(int i=0;i<count;i++)
{
DoSomething();
this.Dispatcher.BeginInvoke((Action)delegate(){
this.progressBar.Value = (int)((100*i)/count);
});
}
WinForms:
// assuming "this" is the window containing your progress bar..
// following code runs in background worker thread...
for(int i=0;i<count;i++)
{
DoSomething();
this.Invoke(delegate(){
this.progressBar.Value = (int)((100*i)/count);
});
}
для делегата WinForms может потребовать некоторого преобразования или вам может потребоваться небольшая помощь, не помните точный синтаксис.
Идея отчета о ходе выполнения с фоновым рабочим процессом заключается в отправке события «процент выполнения». Вы сами несете ответственность за то, чтобы каким-то образом определить, «сколько» работы было выполнено. К сожалению, это часто самая сложная часть.
В вашем случае большая часть работы связана с базой данных. Насколько мне известно, нет способа напрямую получить информацию о ходе выполнения из БД. Однако вы можете попробовать динамически разделить работу. Например, если вам нужно прочитать много данных, это может быть наивным способом.
Разделите фактическое чтение на более мелкие порции, сообщая о прогрессе каждый раз, когда один кусок завершен:
for (int i = 0; я <количество; я ++)
{
bgWorker.ReportProgress ((100 * я) / счетчик);
// ... (считываем данные для шага i)
}
Я не скомпилировал это, поскольку это предназначено для подтверждения концепции. Вот как я реализовал индикатор выполнения для доступа к базе данных в прошлом. В этом примере показан доступ к базе данных SQLite с использованием модуля System.Data.SQLite
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
using(SQLiteConnection cnn = new SQLiteConnection("Data Source=MyDatabase.db"))
{
cnn.Open();
int TotalQuerySize = GetQueryCount("Query", cnn); // This needs to be implemented and is not shown in example
using (SQLiteCommand cmd = cnn.CreateCommand())
{
cmd.CommandText = "Query is here";
using(SQLiteDataReader reader = cmd.ExecuteReader())
{
int i = 0;
while(reader.Read())
{
// Access the database data using the reader[]. Each .Read() provides the next Row
if(worker.WorkerReportsProgress) worker.ReportProgress(++i * 100/ TotalQuerySize);
}
}
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Notify someone that the database access is finished. Do stuff to clean up if needed
// This could be a good time to hide, clear or do somthign to the progress bar
}
public void AcessMySQLiteDatabase()
{
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork +=
new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(
backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged +=
new ProgressChangedEventHandler(
backgroundWorker1_ProgressChanged);
}
Если вы не можете знать прогресс, вам не следует подделывать его, злоупотребляя индикатором выполнения, вместо этого просто отобразите какой-то значок занятости, например en.wikipedia. org / wiki / Throbber # Spinning_wheel Показывать при запуске задачи и скрывать, когда она завершена. Это сделало бы графический интерфейс более «честным».