Parallel.ForEach 루프에서 공유 리소스에 대한 액세스를 어떻게 제어합니까? 여러 파일을 동시에 다운로드하려고하는데 실패한 다운로드에 대한 정보를 캡처하여 나중에 사용자가 다운로드를 다시 시도 할 수있게하려고합니다. 그러나 하나 이상의 스레드가 동시에 다른 스레드에 의해 쓰여지는 동안 파일에 액세스하려고 시도하기 때문에 둘 이상의 다운로드가 동시에 실패하는 경우 응용 프로그램에서 예외가 발생합니다.Parallel.ForEach의 공유 리소스
아래 코드에서 RepeateRequestPath에서 파일에 대한 액세스를 제어하는 방법을 알고 싶습니다. RequestSet은 다운로드하려고하는 리소스의 ID를 나타내는 문자열 목록입니다.
Dim DownloadCnt As Integer = 0
Dim ParallelOpts As New ParallelOptions()
ParallelOpts.MaxDegreeOfParallelism = 4
Parallel.ForEach(RequestSets, ParallelOpts, Sub(RequestSet)
Try
DownloadCnt += 1
Dim XmlUrl As String = String.Format("{0}{1}{2}", "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=", String.Join(",", RequestSet), "&retmode=xml&rettype=abstract")
DownloadFile(XmlUrl, String.Format("{0}\TempXML{1}.xml", XMLCacheDir, DownloadCnt))
Catch ex As WebException
Using Response As WebResponse = ex.Response
Dim statCode As Integer = CInt(DirectCast(Response, HttpWebResponse).StatusCode)
MessageBox.Show(String.Format("Failed to retrieve XML due to HTTP error {0}. Please hit the 'Retrieve XML' button to re-run retrieval after the current set is complete.", statCode))
If Not File.Exists(RepeatRequestPath) Then
File.WriteAllLines(RepeatRequestPath, RequestSet)
Else
File.AppendAllLines(RepeatRequestPath, RequestSet)
End If
End Using
End Try
End Sub)
완벽! 그래도 빠른 질문. Try-Catch 블록의 Try 섹션에서 다른 파일에 대해 동일한 잠금을 사용할 수 있습니까? 아니면 별도의 객체를 인스턴스화해야합니까? 나는 DownloadFile을 호출 한 후에 다른 파일로 똑같은 작업을하고 싶다. – user667118
@ user667118 가능합니다. 또 다른 질문은 하나의 스레드가 하나의 파일에 쓰기를 원할 경우 다른 파일에 쓰는 다른 스레드를 기다려야한다는 것을 의미하기 때문에 그렇게해야하는지 여부입니다. – svick
파일로 쓰는 데 그리 오래 걸리지 않기 때문에별로 문제가되지 않을 것이라고 생각합니다. 전반적으로이 코드는 이전에 동기식으로 실행되었으므로 많은 시간을 절약 할 수 있습니다. – user667118