Вот как бы я это сделал:
Первый:
Мне нравится управлять потоками вручную вместо использования элемента управления BackgroundWorker
при создании многопоточных приложений, подобных тому, которое вы хотите изменить.
Чтобы начать новую тему, это просто:
public void SomeMethod() {
var thread = new Thread(MyMethod);
thread.Start(); //Will start the method
}
public void MyMethod() {
//Do whatever you want inside the thread here
}
Вы можете получить столько экземпляров Thread
, сколько захотите, сохранить их в списке и управлять тем, как предпочитаете. Однако это не правда, что чем больше потоков, тем лучше. Поиск в Google.
Об открытии страниц и хранении файлов cookie.
Я думаю, что у вас может быть экземпляр класса в вашей Форме или где у вас есть логика (в каком-то месте, к которому могут обращаться потоки), (назовем это WebUtils
) с помощью метода, подобного: GoToUrl(<url here>)
или что-то в этом роде и CookieCollection
как поле в этом классе для хранения файлов cookie.
То, что вы должны принять во внимание:
При вызове GoToUrl
может потребоваться блокировка при доступе к переменной cookie, чтобы избежать несоответствия.
Об обновлении элементов управления:
Вы можете создать событие внутри класса WebUtils
, и каждый раз, когда к странице обращаются, вы можете запустить это событие. Перед запуском потоков вы должны подписаться на событие в Form
, вы можете сделать что-то похожее с lock при обновлении / доступе / изменении элементов управления в вашей форме.
Теперь, как избежать сообщения Control ____ accessed from a thread other than the thread it was created...
?
Вот пример:
Если вы хотите изменить свойство Text
элемента управления textBox1
, вместо того, чтобы просто выполнить:
textBox1.Text = "Ey, I accessed the site
вы можете сделать:
MethodInvoker m = () => { textBox1.Text = "Ey, I accessed the site" };
if (InvokeRequired)
BeginInvoke(m);
else
m.Invoke()
Убедитесь, что все модификации сделаны так.
Это всего лишь обзор. Я не специалист по ниткам.
Вот хорошая ссылка на потоки в целом: Threading в C #
Edit:
Посмотрите на свойство потоков IsBackground
. Это может быть причиной зависания приложения, если вы просто хотите его использовать.
Я предложил создать класс WebUtils
, или как вы хотите его назвать, потому что так я его создал в прошлом.
Что-то вроде:
public class WebUtils {
CookieContainer _cookies;
public WebUtils() {
_cookies = new CookieContainer();
}
public void AccessPage(string url) {
//Here I create a new instance of a HttpWebRequest class, and assign `_cookies` to its `Cookie` property.
//Don't really know if `WebClient` has something similar
}
}