Страница: 1 | 2 | 3 |
|
Вопрос: Последовательность в многопоточности
|
Добавлено: 29.08.10 13:11
|
|
Номер ответа: 17 Автор ответа: Artyom
Разработчик
Вопросов: 130 Ответов: 6602
|
Профиль | | #17
|
Добавлено: 30.08.10 23:18
|
EROS пишет:
а потокобезопасный в том плане что мы никогда не получим Cross-Thread Excepthion или, что чаще всего бывает с другими коллекциями, Collection was modified
При чем здесь Cross-Thread Exception? Он относится в Windows Forms а не к этим структурам.
Collection was modified не падает, но падают другие - System.IndexOutOfRangeException и System.ArgumentException, абсолютно неинформативные, но по той же причине - коллекция была модифицирована.
Если класс потокобезопасный, то с ним можно работать без использования критических секций, это, собственно, и есть суть потокобезопасности. Если, чтоб класс заработал, приходится обвешивать его критическими секциями везде где можно, то он уже никакой не потокобезопасный.
Ответить
|
Номер ответа: 20 Автор ответа: Nevep
Вопросов: 6 Ответов: 25
|
Профиль | | #20
|
Добавлено: 01.10.10 00:39
|
EROS, Artyom спасибо за подробное описание... Вроде бы разобрался с потоками, теперь запускаются последовательно, BlockingCollection не применял. Вопрос по функции, запускается допустим 10 потоков (10 ссылок в массиве links), в каждом потоке переменной main(param) присваивается возвращённое функцией значение fnc(param). Проблема в том что значение переменной main(param) присваивается через раз...
- Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
-
- _pool = New Semaphore(0, links.Length)
- _pool.Release(links.Length)
- Dim g
- For g = 0 To links.Length - 1
- ReDim Preserve main(g + 1)
- ReDim Preserve htmlmain(g + 1)
- t = New Thread(New ParameterizedThreadStart(AddressOf stt))
- t.Start(g)
- Next
-
- End Sub
-
- Private Sub stt(ByVal param)
- _pool.WaitOne()
- Try
- main(param) = fnc(param)
- log(param & "log.txt", main(param))
- Catch ex As Exception
- End Try
- _pool.Release()
- End Sub
-
- Function fnc(ByVal param)
-
- Try
- Dim request As HttpWebRequest
- Dim response As HttpWebResponse
- Dim reader As StreamReader
-
- request = WebRequest.Create(links(param))
- request.Method = "GET"
- request.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows 95; MSIECrawler)"
- request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
- response = request.GetResponse()
- reader = New StreamReader(response.GetResponseStream())
- htmlmain(param) = reader.ReadToEnd
- response.Close()
-
- Catch ex As Exception
- MsgBox(123)
- End Try
- Return (param)
- End Function
-
- Function log(ByVal putt, ByVal textanama)
- Dim fFile As Short
- fFile = FreeFile()
- FileOpen(fFile, putt, OpenMode.Append)
- PrintLine(fFile, textanama)
- FileClose(fFile)
- End Function
Ответить
|
Номер ответа: 22 Автор ответа: Artyom
Разработчик
Вопросов: 130 Ответов: 6602
|
Профиль | | #22
|
Добавлено: 01.10.10 13:57
|
nevep, ни какого понятия о потокобезопасности (не говоря о типизации)
Во-первых, main и htmlmain должны быть проинициализированы до начала цикла
Во-вторых, в VB в массивах указывается не размер массива, а верхняя граница, т.е. вместо g+1 нужно просто g (в отличие от C#)
В-третьих, зачем нужен Semaphore, если ты его инициализируешь кол-вом потоков? Он в данном случае абсолютно бесполезен
В-четвертых, в методе log должна быть синхронизация, чтоб несколько потоков не могли одновременно модифицировать файл.
В-пятых, HttpWebResponse, StreamReader реализуют IDisposable и должны использоваться в блоках using для своевременного освобождения подключений
В-шестых, по умолчанию HttpWebRequest может выполнять не более 2 одновременных запросов к одному и тому же серверу, поэтому если у тебя запросы идут к одному серверу, то у тебя одновременно будет скачивать инфу только 2 потока, остальные ждать в очереди.
Ответить
|
Номер ответа: 23 Автор ответа: Nevep
Вопросов: 6 Ответов: 25
|
Профиль | | #23
|
Добавлено: 01.10.10 19:45
|
Тебе не кажется, что это полная чушь?
на самом деле fnc(param) возвращает htmlmain(param)
Во-первых, main и htmlmain должны быть проинициализированы до начала цикла
добавил Dim main, htmlmain
В-третьих, зачем нужен Semaphore, если ты его инициализируешь кол-вом потоков? Он в данном случае абсолютно бесполезен
забыл убрать, просто мне нужно ограничивать кол-во потоков
В-четвертых, в методе log должна быть синхронизация, чтоб несколько потоков не могли одновременно модифицировать файл.
Сделаю, в данном примере каждый раз запись в отдельный файл
В-шестых, по умолчанию HttpWebRequest может выполнять не более 2 одновременных запросов к одному и тому же серверу
Запросы идут к разным серверам
 im main, htmlmain
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' links-массив ссылок
 im g
For g = 0 To links.Length - 1
ReDim Preserve main(g)
ReDim Preserve htmlmain(g)
t = New Thread(New ParameterizedThreadStart(AddressOf stt))
t.Start(g)
Next
'запускаем столько потоков сколько ссылок в массиве links
End Sub
Private Sub stt(ByVal param)
Try
'Присваиваем элементу массива хтмл код страницы
main(param) = fnc(param)
log(param & "log.txt", main(param))
Catch ex As Exception
End Try
End Sub
Function fnc(ByVal param)
'функция получения хтмл кода страниц
Try
 im request As HttpWebRequest
 im response As HttpWebResponse
 im reader As StreamReader
request = WebRequest.Create(links(param))
request.Method = "GET"
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows 95; MSIECrawler)"
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
response = request.GetResponse()
reader = New StreamReader(response.GetResponseStream())
htmlmain(param) = reader.ReadToEnd
response.Close()
'MsgBox(param)
Catch ex As Exception
MsgBox(123)
End Try
Return (htmlmain(param))
End Function
Function log(ByVal putt, ByVal textanama)
 im fFile As Short
fFile = FreeFile()
FileOpen(fFile, putt, OpenMode.Append)
PrintLine(fFile, textanama)
FileClose(fFile)
End Function
Проблема осталась, это из-за IDisposable?
Ответить
|
Номер ответа: 24 Автор ответа: Nevep
Вопросов: 6 Ответов: 25
|
Профиль | | #24
|
Добавлено: 01.10.10 19:46
|
упс...забыл код в тег
- Dim main, htmlmain
- Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
-
- Dim g
- For g = 0 To links.Length - 1
- ReDim Preserve main(g)
- ReDim Preserve htmlmain(g)
- t = New Thread(New ParameterizedThreadStart(AddressOf stt))
- t.Start(g)
- Next
-
- End Sub
-
- Private Sub stt(ByVal param)
- Try
-
- main(param) = fnc(param)
- log(param & "log.txt", main(param))
- Catch ex As Exception
- End Try
- End Sub
-
- Function fnc(ByVal param)
-
- Try
- Dim request As HttpWebRequest
- Dim response As HttpWebResponse
- Dim reader As StreamReader
-
- request = WebRequest.Create(links(param))
- request.Method = "GET"
- request.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows 95; MSIECrawler)"
- request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
- response = request.GetResponse()
- reader = New StreamReader(response.GetResponseStream())
- htmlmain(param) = reader.ReadToEnd
- response.Close()
-
- Catch ex As Exception
- MsgBox(123)
- End Try
- Return (htmlmain(param))
- End Function
-
- Function log(ByVal putt, ByVal textanama)
- Dim fFile As Short
- fFile = FreeFile()
- FileOpen(fFile, putt, OpenMode.Append)
- PrintLine(fFile, textanama)
- FileClose(fFile)
- End Function
Ответить
|
Номер ответа: 28 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #28
|
Добавлено: 01.10.10 22:50
|
Во-первых, main и htmlmain должны быть проинициализированы до начала цикла
Во-вторых, в VB в массивах указывается не размер массива, а верхняя граница, т.е. вместо g+1 нужно просто g (в отличие от C#)
В-третьих, зачем нужен Semaphore, если ты его инициализируешь кол-вом потоков? Он в данном случае абсолютно бесполезен
В-четвертых, в методе log должна быть синхронизация, чтоб несколько потоков не могли одновременно модифицировать файл.
В-пятых, HttpWebResponse, StreamReader реализуют IDisposable и должны использоваться в блоках using для своевременного освобождения подключений
В-шестых, по умолчанию HttpWebRequest может выполнять не более 2 одновременных запросов к одному и тому же серверу, поэтому если у тебя запросы идут к одному серверу, то у тебя одновременно будет скачивать инфу только 2 потока, остальные ждать в очереди.
Какие из этих рекомендаций ты принял к сведению и воплотил в коде?
Ответить
|
Страница: 1 | 2 | 3 |
Поиск по форуму