Во-первых, позвольте мне сказать, что вы не выполняете многопоточность, если это не является абсолютно необходимым. Попытка избежать и оптимизировать ваш код наиболее опытным способом будет как-то лучше, так как вы избежите проблем с многопоточностью.
Во-вторых, класс BackgroundWorker - хорошее начало. Вам нужно будет создать столько экземпляров, сколько вам потребуется для запуска потоков. Для каждого из них вам придется кодировать метод DoWork () . Этот метод вызывается при запуске его операции путем вызова метода BackgroundWorker.RunWorkerAsync () . Код, который вы хотите поместить в событие DoWork (), - это код, который должен асинхронно выполняться в фоновом режиме, пока основной поток вашего приложения занят чем-то другим. Два других события: ProgressChanged () и RunWorkerCompleted () используются для ReportProgress () или для определения того, что делать, когда поток выполнит свою работу, независимо от того, к какому концу это относится (исключение, правильное завершение и т. д.), я использую BackgroundWorker большую часть времени, так как, с моей скромной точки зрения, он наиболее прост в использовании.
В-третьих, вы можете использовать класс System.Threading.Thread . Это немного сложнее, чем просто определить событие DoWork () и заставить его произойти, вызвав другой метод. Вам нужно будет познакомиться с делегатами . Короче говоря, делегаты - это типы методов или функций, которые используются для выполнения некоторой работы в фоновом режиме. Что касается этих делегатов, у вас может быть несколько методов одного и того же типа делегата, как я только что сказал, делегаты являются типами методов. У вас может быть несколько ссылок на делегата . Вы можете увидеть это также как сигнатуру метода. Затем, когда приходит время его использовать, вы должны ссылаться на метод для нужного делегата. Используя класс System.Threading.Thread, вы хотите обратить внимание на делегат ThreadStart .
delegate void DoWork(object sender);
private void btnProcessWork_Click(object sender, EventArgs e) {
DoWork doWork = SimpleDoWorkMethod;
// Then start using the delegate.
Thread t = new Thread(new ThreadStart(doWork));
t.Start(); // Launch the thread in background...
// Do something else while the thread is working !!!
}
private void SimpleDoWorkMethod(object s) {
// Do some work here...
}
В-четвертых, представьте делегатов как событие, поскольку события основаны на делегатах. На самом деле, вы предоставляете метод, который будет использоваться для обработки события, например, Button_Click (). Чтобы программно связать ваше событие btnProcess.Click с методом btnProcess_Click (), вам нужно написать:
btnProcess.Click += new EventHandler(btnProcess_Click);
То, что вы делаете здесь, это делает событие btnProcess.Click ссылкой на ваш метод btnProcess_Click (). Обратите внимание на делегат EventHandler с делегатом ThreadStart. Они служат для той же цели, но для двух разных реальностей (реакция на события в графическом интерфейсе и многопоточность).
В-пятых, не забудьте заблокировать переменную перед тем, как получить к ней доступ, в то время как другой может захотеть получить к ней доступ примерно в одно и то же время, а затем создать перекрестную нить или около того, и это, даже для примитивных типов, но более конкретно для коллекции, так как они не являются поточно-ориентированными.
Надеюсь, это немного поможет! =)