나는 다음과 같은 클래스가 : Task.WaitAll은 차단하고 무기한
class MultiWebProgram
{
static void Main(string[] args)
{
string[] websites = new string[]
{
"https://www.google.com/search?q=one",
"https://www.google.com/search?q=two",
"https://www.google.com/search?q=three",
"https://www.google.com/search?q=four"
};
Task<int>[] taskList = new Task<int>[websites.Length];
int i = 0;
foreach(var website in websites)
{
taskList[i] = Task<int>.Run(() => GetSiteBytes(website));
i++;
}
Task.WaitAll(taskList);
}
public static int GetSiteBytes(string website)
{
WebClient client = new WebClient();
var stream = client.OpenRead(new Uri(website));
byte[] buffer = new byte[4096];
int totalBytes = 0;
int bytesRead = 0;
do
{
bytesRead = stream.Read(buffer, 0, 4096);
totalBytes += bytesRead;
}
while (bytesRead >= 4096);
Console.WriteLine("Got {0} bytes from {1}", totalBytes, website);
return totalBytes;
}
}
나는이 실행
의WaitAll
명령에 코드 블록.
나는이에 프로그램을 변경 시도 :
class MultiWebProgram
{
static void Main(string[] args)
{
string[] websites = new string[]
{
"https://www.google.com/search?q=one",
"https://www.google.com/search?q=two",
"https://www.google.com/search?q=three",
"https://www.google.com/search?q=four"
};
Task<int>[] taskList = new Task<int>[websites.Length];
int i = 0;
foreach(var website in websites)
{
taskList[i] = GetSiteBytesAsync(website);
i++;
}
Task.WaitAll(taskList);
}
public async static Task<int> GetSiteBytesAsync(string website)
{
WebClient client = new WebClient();
var stream = await client.OpenReadTaskAsync(new Uri(website));
byte[] buffer = new byte[4096];
int totalBytes = 0;
int bytesRead = 0;
do
{
bytesRead = await stream.ReadAsync(buffer, 0, 4096);
totalBytes += bytesRead;
}
while (bytesRead >= 4096);
Console.WriteLine("Got {0} bytes from {1}", totalBytes, website);
return totalBytes;
}
}
을 즉, 나는 GetSiteBytes 방법 비동기했다 -하지만 차이를하지 않았다.
내가 한 일은주의해야합니다. 피들러를 시작하고 두 버전의 프로그램을 실행했을 때 차단이 없었습니다.
여기에 무슨 일이 일어날 수 있습니까?
** 편집 : ** 문제는 OpenRead 메소드 인 것 같습니다. DownloadData/DownloadDataAsync를 사용하면 차단이 사라졌습니다.
하나 이상의 작업을 완료하지 못하면 Task.WaitAll()이 무기한 차단됩니다. 따라서 왜 블록 하는지를 묻는 것보다 작업 중 하나가 완료되지 않는 이유를 묻는 것이 좋습니다. 하지만 먼저 프로세스를 디버그하고 완료되지 않은 프로세스를 식별해야합니다. 결국, google.com이 동일한 클라이언트의 네 가지 동시 요청 (피들러가 일을 진행하기에 충분히 혼란 스러울 수 있음)을 인식하지 못할 수도 있습니다. 그러나 더 나은 질문이 없으면 해결책을 제시하는 것이 어려울 것입니다. –
"무기한으로"말할 때 얼마나 기다렸습니까? 나를 위해, 시간은 약 2 분입니다. – svick
그냥 몇 가지 추가 정보, 구글은 화면을 scrapers을 좋아하지 않아 그것을 방지하기 위해 장소에 많은 컨트롤이 있습니다. google.com으로 테스트하는 경우 많은 문제가 발생할 것입니다. 자신의 사이트에서 테스트하는 것이 가장 좋습니다. –