С одной стороны, в размещенном коде недостаточно контекста, чтобы получить полную картину, чтобы ответить на ваши вопросы точно . Однако мы можем вывести, что происходит не так, просто из кода, который вы опубликовали.
Во-первых, давайте попробуем ответить на два ваших вопроса. Мы можем вывести следующее:
Этот код здесь:
if (e.UserState != null)
{
Data.Add(new Operations()
{
id = rnd.Next(1,999),
name = Factory.name,
qtyStock = Factory.Stock,
averageStock = Factory.AverageStock,
week = Factory.Week
});
listview.ItemsSource = Data;
}
Вы используете объект фонового потока Windows Forms, чтобы попытаться обновить объект WPF GUI, который должен только быть сделано в основном потоке GUI. Существует также очевидное «нет-нет» - никогда не обновлять GUI объекты из не-пользовательских потоков. Использование BackgroundWorker
также имеет свои проблемы с многопоточностью (передний план / фон), контекстами и выполнением, так как для выполнения работы используются Dispatcher
и SynchronizationContexts
.
Тогда возникает любопытство установки привязки снова и снова в этой строке:
listview.ItemsSource = Data;
Давайте на мгновение вставим булавку в это ...
Есть, как и другие указатель на комментатор уже отсутствует, у вас нет стратегии выхода l oop:
while (Factory.Week < max) // max = 52
{
if (worker.CancellationPending) // also this isn't reacting to worker.CancelAsync();
e.Cancel = true;
// My teacher tried to call my threads from here, but it breaks the purpose of having
// two threads as he was just calling 52 times two functions back to back and therefore
// wasn't "randomizing" the transactions.
int progressPercentage = Convert.ToInt32(((double)(Factory.Week) / max) * 100);
(sender as BackgroundWorker).ReportProgress(progressPercentage, Factory.Week);
}
Но это не самая большая проблема ... в дополнение к неправильному использованию / неправильному пониманию того, когда / сколько / как использовать Похоже, что нет никакой синхронизации потоков. Таким образом, нет никакого способа предсказать или отследить выполнение времени жизни потока.
На данный момент на вопрос технически более или менее ответили, но я чувствую, что это просто оставит вас более расстроенным и не лучше, чем ты начал. Так что, может быть, быстрый краткий курс sh по основам дизайна c может помочь исправить этот беспорядок, что должен был сделать ваш учитель.
Предполагая, что вы занимаетесь разработкой программного обеспечения, и поскольку вы выбрали WPF здесь как ваш «макет», так сказать, вы, скорее всего, встретите такие термины, как MVC (контроллер вида модели) или MVVM (вид модели модели). Скорее всего, вы также столкнетесь с принципами проектирования, такими как SOLID, разделение задач и группировка вещей в сервисы.
Ваш код здесь - прекрасный пример того, почему существуют все эти платформы и принципы. Давайте рассмотрим некоторые проблемы, с которыми вы столкнулись, и способы их устранения:
У вас есть многопоточный код (logi c и services - controller [свободно говоря]), смешанный с презентацией код (listview update - view) и обновление коллекции (ваша наблюдаемая коллекция - модель). Это одна из причин (из многих), что вы сталкиваетесь с трудностями при написании кода, исправлении и поддержании проблемы под рукой. Чтобы очистить это, отделите это (разделение проблем). Вы можете даже переместить каждую операцию в свой собственный класс с интерфейсом / API для этого класса (сервис / микросервис).
Не все нужно решать с помощью потоков. Но сейчас давайте научимся ползать, а затем идти, прежде чем бежать. Прежде чем вы начнете изучать async / await или TPL (библиотека параллельных задач), давайте go old school. Получить хорошую книгу ... что-то даже из 20 лет go это найти ... go старую школу, и научиться использовать ThreadPool и объекты синхронизации ядра, такие как мьютексы, события и т. Д. c и как сигнализировать между потоками. Как только вы овладеете этим, то узнайте о TPL и async / await.
Не пересекать потоки. Не смешивайте WinForms, WPF и я даже видел Console.WriteLine
.
Узнайте о привязке данных и, в частности, как она работает в WPF. ObservableCollection
ваш друг, привяжите к нему ItemsSource
один раз , затем обновите ObservableCollection
и оставьте объект GUI в покое.
Надеюсь, это поможет вам исправить код и запустить его в действие.
Удачи!