检测 webclient 的 DownloadComplete 事件处理程序执行是否完成?
Detect if webclient's DownloadComplete event handler execution finished?
我是整个 Async
和 Threading
编程世界的新手。我被困在一个问题上。以下代码是为了更好地理解而简化的版本。
我正在努力做的三件事,
1) 使用 WebClient
循环点击 api,这是 Async
方法并开始下载数据
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=Whosebug"), 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);
}
}
}
如有困惑,请随时发表评论。如果还有其他方法可以实现我正在做的事情,请随意提及。无需按照我的方法,如果您有其他方法,请免费 comment.Any 指点的话,答案会很好。
作为旁注,您可以使用 Microsoft Async 在 .NET 4.0
上使用 async-awit
所以,你需要有一些方法来等待一系列的结束 "tasks"。
既然您似乎知道自己有多少 "tasks",那么 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=Whosebug"), 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();
}
}
}
我是整个 Async
和 Threading
编程世界的新手。我被困在一个问题上。以下代码是为了更好地理解而简化的版本。
我正在努力做的三件事,
1) 使用 WebClient
循环点击 api,这是 Async
方法并开始下载数据
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=Whosebug"), 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);
}
}
}
如有困惑,请随时发表评论。如果还有其他方法可以实现我正在做的事情,请随意提及。无需按照我的方法,如果您有其他方法,请免费 comment.Any 指点的话,答案会很好。
作为旁注,您可以使用 Microsoft Async 在 .NET 4.0
上使用async-awit
所以,你需要有一些方法来等待一系列的结束 "tasks"。
既然您似乎知道自己有多少 "tasks",那么 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=Whosebug"), 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();
}
}
}