I'm trying to use an AutoResetEvent object to block the thread until the async. download of a WebClient is done.
My problem is that once I call WaitOne(), the thread just locks there and VS never reaches the breakpoint in the DownloadComplete event handler method.
Here's my code
//Class used to pass arguments to WebClient's events...
public class RunArgs
{
public JobInfo jobInfo;
public int jobTotal;
public int jobIndex;
public AutoResetEvent AutoResetEventObject;
}
List<JobInfo> jl = ConfigSectionWrapper.GetAllJobs();
int jobAmount = jl.Count;
int jobIndex = 0;
RunArgs args = new RunArgs();
args.jobTotal = jl.Count;
foreach (JobInfo ji in jl)
{
if (ji.enabled == "0")
{
args.jobIndex++;
continue;
}
try
{
args.jobIndex++;
args.jobInfo = ji;
appLog.Source = ji.eventSource;
appLog.WriteEntry(string.Format("Started job {0}...", ji.jobName), EventLogEntryType.Information);
ji.fullFileName = string.Format(ji.reportFileName, string.Format("{0}-{1}-{2}", DateTime.Now.Year.ToString(), DateTime.Now.Month.ToString().PadLeft(2, '0'), DateTime.Now.Day.ToString().PadLeft(2, '0')));
ji.fullFileName = string.Format("{0}{1}", ji.downloadDirectory, ji.fullFileName);
using (WebClient wc = new WebClient())
{
AutoResetEvent notifier = new AutoResetEvent(false);
args.AutoResetEventObject = notifier;
wc.Credentials = CredentialCache.DefaultNetworkCredentials;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadCompleted);
wc.DownloadFileAsync(new Uri(args.jobInfo.reportURL), args.jobInfo.fullFileName, args); //Pass the args params to event handler...
notifier.WaitOne();
}
}
catch (Exception ex)
{
appLog.WriteEntry(string.Format("Error starting report execution: {0}", ex.Message), EventLogEntryType.Error);
DeleteFile(ji.fullFileName);
}
}
private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
RunArgs args = (RunArgs)e.UserState;
//Do things....
args.AutoResetEventObject.Set();
}
So I instantiate notifier with false in the constructor, because I don't want its status to be signaled already. Unless I'm reading MSDN wrong ?
Anything obviously wrong ?
Here's what I ended up doing:
private AutoResetEvent notifier = new AutoResetEvent(false);
Now the main loop looks like:
foreach (JobInfo ji in jl)
{
if (ji.enabled == "0")
{
args.jobIndex++;
continue;
}
args.jobInfo = ji;
Thread t = new Thread(new ParameterizedThreadStart(startDownload));
t.Start(args);
notifier.WaitOne();
}
private void startDownload(object startArgs)
{
RunArgs args = (RunArgs)startArgs;
try
{
args.jobIndex++;
appLog.Source = args.jobInfo.eventSource;
appLog.WriteEntry(string.Format("Started job {0}...", args.jobInfo.jobName), EventLogEntryType.Information);
args.jobInfo.fullFileName = string.Format(args.jobInfo.reportFileName, string.Format("{0}-{1}-{2}", DateTime.Now.Year.ToString(), DateTime.Now.Month.ToString().PadLeft(2, '0'), DateTime.Now.Day.ToString().PadLeft(2, '0')));
args.jobInfo.fullFileName = string.Format("{0}{1}", args.jobInfo.downloadDirectory, args.jobInfo.fullFileName);
WebClient wc = new WebClient();
wc.Credentials = CredentialCache.DefaultNetworkCredentials;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadCompleted);
wc.DownloadFileAsync(new Uri(args.jobInfo.reportURL), args.jobInfo.fullFileName, args); //Pass the args params to event handler...
}
catch (Exception ex)
{
appLog.WriteEntry(string.Format("Error starting report execution: {0}", ex.Message), EventLogEntryType.Error);
DeleteFile(args.jobInfo.fullFileName);
notifier.Set();
}
}
So now the AutoResetEvent is blocking the main thread but t can successfully trigger the DownloadFileCompleteEvent. And in the DownloadFileCompleted event, I'm obviously doing a notifier.Set() too.
Thanks all!