Переменная класса, заданная BackgroundWorker, не сохраняется.

Я совершенно новичок в идее BackgroundWorkers, так что это меня немного озадачивает.

Поэтому я создал новое приложение WPF и создал переменную класса BackgroundWorker и List:

public partial class MainWindow : Window
{
 private BackgroundWorker bw = new BackgroundWorker();
 private List<int> tempList = new List<int>();
 ...
</int></int>

Затем я использую BackgroundWorker для заполнения этого списка: (В том же классе btw)

private void bw_DoWork(object sender, DoWorkEventArgs e)
 {
 BackgroundWorker worker = sender as BackgroundWorker;
 Random r = new Random();
 for (int j = 1; j <= 100; j++)
 {
 for (int i = 0; i < 1000; i++)
 {
 tempList.Add(r.Next(100));
 }
 ...
 }
 }

Теперь вот часть, которая заставляет меня...

Код, который заполняет этот список, кажется, работает нормально. Когда я выполняю его выполнение, * он ведет себя так, как я предполагал, до момента, когда код выходит из метода bw_DoWork. * После этого он возвращается в пустой список. Я изменил список на статический в какой-то момент, но ничего не изменилось.

Итак, почему этот список не сохраняется во время выполнения программ?

Я (был) почти уверен, что это определенная проблема с тем, что список распределяется в разных областях памяти для каждого потока, но я просто слишком мало знаю о BackgroundWorker и MultiThreading в целом, чтобы самому диагностировать его.

Любая помощь будет оценена по достоинству.

2 ответа

Прежде чем приступать к использованию более дорогих опций, таких как блокировка или сборка потоковой безопасности. Попробуйте задачи Threading. Если они работают, у вас есть какая-то проблема с вашим BackgroundWorker, если они этого не сделают, ваш код коснется списка где-нибудь, и вам придется проследить это. (Я просто думаю, что задачи намного легче работать)

private void bw_DoWork()
 {
 Task.Factory.StartNew(
 () =>
 {
 var r = new Random();
 for (int j = 1; j <= 100; j++)
 {
 for (int i = 0; i < 1000; i++)
 {
 tempList.Add(r.Next(100));
 }
 //the rest of whaterver you're doing...
 }
 });
 }


@Stephen Marsh, как @Douglas сказал, что вам нужно подождать, пока работа закончится.

Видеть это:

// this execute the DoWork asynchronously.
bw.RunWorkerAsync();
// asynchronously means the next line may be executed
// before the DoWork fill the list. In fact can be executed
// before the DoWork begin.
MessageBox.Show("Without wait: " + tempList.Count.ToString());

Чтобы исправить это, вы можете добавить эту строку перед вызовом RunWorkerAsync:

bw.RunWorkerCompleted += bw_RunWorkerCompleted;

и поместите это в любом месте класса MainWindows.

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
 MessageBox.Show("Completed: " + tempList.Count.ToString());
}

В моих тестах всегда был результат:

"Without wait: 0"
"Completed: 100000"

licensed under cc by-sa 3.0 with attribution.