我从网上下载了很多网址,但我不知道所有的网址何时完成下载。与此同时,我写了一些东西,但它似乎太垃圾了,虽然它有效。
在我的代码中,我从dtPP
dataTable下载了所有网址,并将其保存到matUrlFharsing
数组。
这是我的代码:
main()
{
Parallel.For(0, dtPP.Rows.Count, i =>
{
string f = "";
WebClient client = new WebClient();
client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
lock (dtPP.Rows[i])
{
f = dtPP.Rows[i]["pp_url"].ToString();
}
client.DownloadDataAsync(new Uri(f), i);
});
while (end)
{
}
DoSomething();
}
void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
int h = (int)e.UserState;
page = (int)e.UserState;
myString = enc.GetString(e.Result);
lock (matUrlFharsing[h])
{
lock (dtPP.Rows[h])
{
//save in mat
matUrlFharsing[h] = Pharsing.CreateCorrectHtmlDoc(myString);
}
}
lock (myLocker)
{
ezer = false;
for (int j = 0; j < matUrlFharsing.Length && !ezer; j++)
{
if (matUrlFharsing[j] == "")
ezer = true;
}
end = ezer;
}
}
我可以做些什么来改进或改变它?
答案 0 :(得分:4)
小改进:
使用AutoResetEvent代替bool for End。
AutoResetEvent autoResetEvent;
main()
{
autoResetEvent = new AutoResetEvent(false);
Parallel.For(0, dtPP.Rows.Count, i =>
{
// your code
});
autoResetEvent.WaitOne();
DoSomething();
}
void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
...
if(ezer)
{
autoResetEvent.Set();
}
}
答案 1 :(得分:1)
您可以使用AutoResetEvent数组,将它们作为参数发送到事件接收器并等待它们。
AutoResetEvent[] autoResetEvents;
main()
{
autoResetEvent = new AutoResetEvent[dtPP.Rows.Count];
Parallel.For(0, dtPP.Rows.Count, i =>
{
string f = "";
WebClient client = new WebClient();
client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
lock (dtPP.Rows[i])
{
f = dtPP.Rows[i]["pp_url"].ToString();
}
Object[] parameters = new Object[2];
autoResetEvents[i] = new AutoResetEvent(false);
parameters[0] = i;
parameters[1] = autoResetEvent[i];
client.DownloadDataAsync(new Uri(f), parameters);
});
WaitHandle.WaitAll(autoResetEvents);
DoSomething();
}
void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
Object[] parameters = (object[])e.UserState;
autoResetEvent = (AutoResetEvent)parameters[1];
int h = (int)parameters[0];
page = (int)e.UserState;
myString = enc.GetString(e.Result);
lock (matUrlFharsing[h])
{
lock (dtPP.Rows[h])
{
//save in mat
matUrlFharsing[h] = Pharsing.CreateCorrectHtmlDoc(myString);
}
}
autoResetEvent.Set();
}
答案 2 :(得分:0)
异步功能完成后,将调用已完成的事件。你走在正确的道路上......
您可以在While(结束)中改进代码。这个While语句运行得非常快。你可以: