I am not sure if this is the proper place to ask, but this site has always been a trememdous help for me in other areas.
I have a perfect candidate for background threading in a small, personal Winforms application I am writing, and I am seeking help in trying to implement it properly/correctly.
This is the call from the presentation layer:
private void btnGetSeasonSchedule_Click(object sender, EventArgs e){
Cursor.Current = Cursors.WaitCursor;
objSchedule.RetreiveSeasonSchedule();
MessageBox.Show("Finished");
Cursor.Current = Cursors.Default;
}
This is the code in the BLL:
public class SeasonSchedule{
public ForumAssistantDAL.SeasonSchedule objSchedule = new ForumAssistantDAL.SeasonSchedule();
public void RetreiveSeasonSchedule(){
DataTable dtData = GetGamesInRange(DateTime.Parse("2015-10-07"), DateTime.Parse("2016-04-30"));
// this call is to an SQLBulkUpdate function in the DAL
objSchedule.UploadSchedule(dtData);
}
// ***** BackgroundWorker Candidate #1 *****
// my first thought is to have the entire function below as a backgroundworker process
//as it is used in a few other locations in the application *****
private DataTable GetGamesInRange(DateTime startDate, DateTime endDate){
DataTable dtScheduleTable = objSchedule.CreateScheduleTable();
// ***** BackgroundWorker Candidate #1 *****
// instead of the entire function, just put this ForEach loop in a BackgroundWorker
foreach (DateTime day in EachDay(DateTime.Parse(startDate.ToString("yyyy-MM-dd")), DateTime.Parse(endDate.ToString("yyyy-MM-dd")))){
//build proper URL using URIBuilder
//...URL requires a formatted date, hence the necessity of re-building it in a foreach loop
var uriBuilder = new UriBuilder();
uriBuilder.Scheme = "http";
uriBuilder.Host = "my.datasource.address";
uriBuilder.Path = "path_part_1/path_part_2/" + day.ToString("yyyy-MM-dd") + ".jsonp";
var uri = uriBuilder.Uri;
try{
string json = new WebClient().DownloadString(uri);
json = json.Replace("loadScoreboard(", "");
json = json.Replace(")", "");
GameCollection gameDay = objSchedule.ParseGames(json);
// ***** BackgroundWorker Candidate #2 *****
// each GameCollection can contain from zero to N games
// each game is added to a temporary DataTable
// when the ForEach loop is complete, the entire DataTable is returned, and the DataTable is SQLBulkCopy-ied to the database server
foreach (DeserializedGame game in gameDay.Games){
objSchedule.InsertGame(game, dtScheduleTable, day);
}
}
catch (WebException ex){
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null){
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.NotFound){
// HTTP 404 - the page was not found, continue with next in the for loop
continue;
}
}
//throw any other exception - this should not occur
throw;
}
}
return dtScheduleTable;
}
private IEnumerable<DateTime> EachDay(DateTime from, DateTime thru){
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
}
My goal is the following:
- multi-thread this application correctly
- once the multi-threading is in place, I to implement two ProgressBars:
- one for the ForEach loop (to track the processing for each day)
- one for each DeserializedGame in the ForEach loop (BackgroundWorker Candidate #2)
I have looked at ThreadStart and ParameterizedThreadStart (which I believe is the proper one to use), but I feel I get very lost, very quickly when it comes to implementing the threading properly and correctly. Threading is a new concept for me, so any "for dummies" help you can offer would be greatly appreciated.