我是编程的整个Async
和Threading
世界的新手。而且我遇到了一个问题。以下代码是简化版本,以便更好地理解。
我想做的三件事,
1)使用WebClient
和Async
方法在循环中点击api并开始下载数据
2)下载api数据时使用该时间处理其他数据并计算一些值
3)确保完成所有下载,然后处理下载的数据并保存到文件和数据库
我能够实现2个步骤但是在第3步中我不知道如何检测是否所有下载都已完成所以用Google搜索并找到this但问题是它需要.net 4.5和我我正在研究 .net 4.0 。所以基本上我需要的解决方案可以帮助我弄清楚如何检测所有api调用的下载是否已完成。
有一种方法可以使用循环调用计数来匹配已完成的数据项列表计数,但是如果只有一个或两个api调用得到错误,那么它将无限期地等待。
以下是我的代码,
class Program
{
public static List<StackRoot> AllQuestionRoot = new List<StackRoot>();
static void Main(string[] args)
{
MyWebClient client = new MyWebClient();
try
{
for (int i = 0; i < 10; i++)
{
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(HandleQuestionDownloadCompleted);
client.DownloadStringAsync(new Uri("http://api.stackexchange.com/2.2/questions?page=1&pagesize=20&order=desc&sort=creation&tagged=reporting-services&site=stackoverflow"), waiter);
}
}
catch (WebException exception)
{
string responseText;
using (var reader = new StreamReader(exception.Response.GetResponseStream()))
{
responseText = reader.ReadToEnd();
}
}
//Do some other stuff
//calculate values
//How to make sure all my asynch DownloadStringCompleted calls are completed ?
//process AllQuestionRoot data depending on some values calculated above
//save the AllQuestionRoot to database and directory
Console.ReadKey();
}
private static void HandleQuestionDownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null || !e.Cancelled)
{
StackRoot responseRoot = JsonConvert.DeserializeObject<StackRoot>(e.Result);
AllQuestionRoot.Add(responseRoot);
}
}
}
如果出现混淆,请随时发表评论。如果有任何其他方式来实现我正在做的事情,请随意提及。没有必要按照我的方法,如果你有任何其他请自由评论。任何指向单词的答案将是伟大的。
答案 0 :(得分:2)
作为旁注,您可以使用Microsoft Async在 .NET 4.0
上使用async-awit
所以,你需要有一些方法等待一系列&#34;任务的结束&#34;。
因为你似乎知道有多少&#34;任务&#34;你有,CountdownEvent非常合适:
class Program
{
public static List<StackRoot> AllQuestionRoot = new List<StackRoot>();
public static object criticalSection = new object();
public static CountdownEvent countdown = new CountdownEvent(10);
static void Main(string[] args)
{
MyWebClient client = new MyWebClient();
try
{
for (int i = 0; i < 10; i++)
{
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(HandleQuestionDownloadCompleted);
client.DownloadStringAsync(new Uri("http://api.stackexchange.com/2.2/questions?page=1&pagesize=20&order=desc&sort=creation&tagged=reporting-services&site=stackoverflow"), waiter);
}
}
catch (WebException exception)
{
string responseText;
using (var reader = new StreamReader(exception.Response.GetResponseStream()))
{
responseText = reader.ReadToEnd();
}
}
//Do some other stuff
//calculate values
//How to make sure all my asynch DownloadStringCompleted calls are completed ?
//process AllQuestionRoot data depending on some values calculated above
//save the AllQuestionRoot to database and directory
// Wait until all have been completed.
countdown.Wait();
Console.ReadKey();
}
private static void HandleQuestionDownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null || !e.Cancelled)
{
StackRoot responseRoot = JsonConvert.DeserializeObject<StackRoot>(e.Result);
// Adding to List<T> is not thread safe.
lock (criticalSection)
{
AllQuestionRoot.Add(responseRoot);
}
// Signal completed.
countdown.Signal();
}
}
}