how to add a new customer in list in c#? - c#

I'm working this code for almost 10 hours but i can not find out where i'm doing wrong .If you could help me you are really making my day.The problem is that I'm trying to add a new customer and save it in my list but when i'm click in submit button .It does not work nothing is saving in my list and keeps looping my other customers .
private void Sub_Click(object sender, RoutedEventArgs e)
{
customer newCus = new customer();
account newAcc= new account();
try
{
newCus.NAME = Nameadd.Text;
newCus.pin = pinadd.Text;
newAcc.PIN = pinadd.Text;
newAcc.accountnumber = Accountnumadd.Text;
newAcc.accounttype = 'C';
for (int i = 0; i < acclist.Count; i++)
{
{
if(newAcc.accounttype == 'C')
{
newAcc.PIN = pinadd.Text;
newAcc.accountnumber = Accountnumadd.Text;
newAcc.accounttype = 'S';
}
}
cuslist.add(newCus);
acclist.add(newAcc);
savefile();
saveaccount();
}
}
catch(Exception error)
{
MessageBox.Show(error.Message);
}
}
//save to customer file
public void savefile()
{
using (StreamWriter writer = new StreamWriter("account.txt"))
{
for (int i = 0; i < cuslist.Count; i++)
{
var info = new List<string>
{
acclist[i].accounttype.ToString(),
acclist[i].PIN,
acclist[i].accountnumber,
acclist[i].accountbalance.ToString()
};
var account = String.Join(";", info);
writer.WriteLine(account);
}
}
}
public void saveaccount()
{
using (StreamWriter writer = new StreamWriter("account.txt"))
{
for (int i = 0; i < acclist.Count; i++)
{
var info = new List<string>
{
acclist[i].accounttype.ToString(),
acclist[i].PIN,
acclist[i].accountnumber,
acclist[i].accountbalance.ToString()
};
var account = String.Join(";", info);
writer.WriteLine(account);
}
}
}

You have a problem in your "save" functions.
Here is what you have:
public void savefile()
{
using (StreamWriter writer = new StreamWriter("account.txt"))
{
for (int i = 0; i < cuslist.Count; i++)
{
var info = new List<string>
{
acclist[i].accounttype.ToString(),
acclist[i].PIN,
acclist[i].accountnumber,
acclist[i].accountbalance.ToString()
};
var account = String.Join(";", info);
writer.WriteLine(account);
}
}
}
public void saveaccount()
{
using (StreamWriter writer = new StreamWriter("account.txt"))
{
for (int i = 0; i < acclist.Count; i++)
{
var info = new List<string>
{
acclist[i].accounttype.ToString(),
acclist[i].PIN,
acclist[i].accountnumber,
acclist[i].accountbalance.ToString()
};
var account = String.Join(";", info);
writer.WriteLine(account);
}
}
}
If you look, the only difference is the for loops. You need to also update the inner portion to read from the correct collection, and also write to the correct output file.
Try the following:
public void savefile()
{
using (StreamWriter writer = new StreamWriter("customer.txt"))
{
for (int i = 0; i < cuslist.Count; i++)
{
var info = new List<string>
{
cuslist[i].accounttype.ToString(),
cuslist[i].PIN,
cuslist[i].accountnumber,
cuslist[i].accountbalance.ToString()
};
var customer = String.Join(";", info);
writer.WriteLine(customer);
}
}
}
public void saveaccount()
{
using (StreamWriter writer = new StreamWriter("account.txt"))
{
for (int i = 0; i < acclist.Count; i++)
{
var info = new List<string>
{
acclist[i].accounttype.ToString(),
acclist[i].PIN,
acclist[i].accountnumber,
acclist[i].accountbalance.ToString()
};
var account = String.Join(";", info);
writer.WriteLine(account);
}
}
}

Related

Missing end of data in created text file

I am trying to save data from public Web API to a txt file. However, it seems that somwhere here
using (var fs = FileService.CreateFile("filename.txt"))
{
// Add some text to file
var title = new UTF8Encoding(true).GetBytes(strContent);
fs.WriteAsync(title, 0, strContent.Length);
}
I am making a mistakes as I am missing some data at the end.
public void GetData()
{
var path = "https://www.cnb.cz/cs/financni-trhy/devizovy-trh/kurzy-devizoveho-trhu/kurzy-devizoveho-trhu/denni_kurz.txt";
string strContent;
var webRequest = WebRequest.Create(path);
using (var response = webRequest.GetResponse())
using(var content = response.GetResponseStream())
using(var reader = new StreamReader(content))
{
strContent = reader.ReadToEnd();
}
using (var fs = FileService.CreateFile("filename.txt"))
{
// Add some text to file
var title = new UTF8Encoding(true).GetBytes(strContent);
fs.WriteAsync(title, 0, strContent.Length);
}
var file = File.ReadAllLines(FileService.ReturnBinLocation("filename.txt"));
var results = new List<string>();
for (var a = 0; a < file.Length; a++)
{
results.Add(file[a]);
File.WriteAllLines(data, results);
}
var sub2 = File.ReadAllText(data);
sub2 = sub2.Replace('\n', '|').TrimEnd('|');
var split = sub2.Split('|');
var list = new List<DailyCourse>();
var i= 0;
do
{
var model = new DailyCourse();
model.Country = split[i]; i++;
model.Currency = split[i]; i++;
model.Amount = split[i]; i++;
model.Code = split[i]; i++;
model.Course = split[i]; i++;
list.Add(model);
} while ( i < split.Length);
var json = JsonSerializer.Serialize(list);
}
public static class FileService
{
public static FileStream CreateFile(string fileName)
{
var wholePath = ReturnBinLocation(fileName);
if (File.Exists(wholePath))
{
File.Delete(wholePath);
}
return File.Create(wholePath);
}
public static string ReturnBinLocation( string fileName)
{
var binPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
var wholePath = Path.Combine(binPath, fileName);
int endIndex = wholePath. Length - 5;
var sub = wholePath.Substring(5, endIndex);
return sub;
}
}
I have actually found out that it was this "Encoding.UTF8.GetBytes"when I switched it to Encoding.ASCII.GetBytes. It worked

I use ".net core" .i want to search any keyword in a pdf file but this code is not working

static void Main(string[] args) {
var file = File.Open(Directory.GetCurrentDirectory() + "/Net.pdf", FileMode.Open);
var pattern = new Regex("kullan", RegexOptions.IgnoreCase);
//this line is not working
TextExtractor textExtractor = new TextExtractor();
var dddd = ReadToEnd(file);
var textStrings = textExtractor.Extract(dddd);
var matches = pattern.Matches(textStrings.Text);
foreach (var item in matches)
{
Console.WriteLine(item);
}
}
You can try something like this:
File file = new File(myPDF);
//pattern
var pattern = new Regex("kullan", RegexOptions.IgnoreCase);
var textExtractor = new TextExtractor();
foreach (var page in file.Document.Pages)
{
var strings = textExtractor.Extract(page);
var matchingText = pattern.Matches(TextExtractor.ToString(strings));
}
Tika:
try
{
var result = new TextExtractor().Extract(yourPDF.pdf).Text;
Console.WriteLine(result.Text.Length);
foreach(var line in result)
{
if(line.contains("kullen"))
/** Do Something **/
}
}
catch(Exception e)
{
Console.WriteLine("Error occurred: " + e);
}
I did it like that, thank you your answer
namespace pro
{
class Program
{
static void Main(string[] args)
{
string b = pdfText(Directory.GetCurrentDirectory()+ "/Net.pdf");
string a= "kullan";
int sonuc;
sonuc = b.IndexOf(a,0, b.Length);
if(sonuc==-1)
{
Console.WriteLine("not found");
}
else
{
Console.WriteLine("found from " + sonuc.ToString() + ". character");
}
}
public static string pdfText(string path)
{
PdfReader reader = new PdfReader(path);
var dd = reader.GetPageContent(1);
string text = string.Empty;
for (int page = 1; page <= reader.NumberOfPages; page++)
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
text += PdfTextExtractor.GetTextFromPage(reader, page);
}
reader.Close();
return text;
}
}
}

How to link a module in asp.net, C# web application in all forms

Is there a way for me to link my module in all of my form i'm using c# app and this is my code. This is actually a notification bell that will notify users if he/she has/have notifications. I already linked it on homepage how am i able to do that in all other pages
private void systemNotificationREXS(HomePage module)
{
TextBox Username = (TextBox)module.FindControl("Hide_user");
Label Fullname = (Label)module.FindControl("userfullname");
Label notifLabel = (Label)module.FindControl("notifLabel");
using (con = new SqlConnection(EXCUSESLPCON))
{
using (cmd = new SqlCommand("SYSTEMNOTIFICATIONEXSLIP", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#userfullname", Fullname.Text);
con.Open();
using(adp = new SqlDataAdapter(cmd))
{
using(dt = new DataTable())
{
adp.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++ )
{
int notifcount = int.Parse(dt.Rows[i]["notifcount"].ToString());
string modulename = dt.Rows[i]["modulename"].ToString();
string modulebody = modulename + "Body";
string moduleLabel = modulename + "Label";
Label namebox = (Label)module.FindControl(modulename);
if (notifcount > 0)
{
namebox.Visible = true;
namebox.Text = notifcount.ToString();
module.FindControl(modulebody).Visible = true;
try
{
module.FindControl(moduleLabel).Visible = true;
}
catch
{
notifLabel.Visible = false;
}
}
else
{
namebox.Visible = false;
module.FindControl(modulebody).Visible = false;
try
{
module.FindControl(moduleLabel).Visible = false;
}
catch
{
notifLabel.Visible = false;
}
}
}
}
}
con.Close();
}
}
}
internal void notificationSystemREXS(string fullname, string hide_user, HomePage modulename)
{
systemNotificationREXS(modulename);
}
Code to linked on homepage:
private void systemNotificationREXS()
{
Notification moduleacc = new Notification();
moduleacc.notificationSystemREXS(userfullname.Text, Hide_user.Text, this);
}
Your method does very simple job, but you have made it complicated and over dependent on the module and other stuff.
The method should return only the notification data for the user and let the caller of the method to decide what to do with the data.
Consider doing following.
public class NotificationData
{
public int NotificationCount {get;set;}
public int ModuleName {get;set;}
}
public class NotificationService
{
public static List<NotificationData> GetNotificationData(string username)
{
var notificationList = new List<NotificationData>();
using (con = new SqlConnection(EXCUSESLPCON))
{
using (cmd = new SqlCommand("SYSTEMNOTIFICATIONEXSLIP", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#userfullname", Fullname.Text);
con.Open();
using(adp = new SqlDataAdapter(cmd))
{
using(dt = new DataTable())
{
for (int i = 0; i < dt.Rows.Count; i++ )
{
var notification = new NotificationData();
notification.NotificationCount = int.Parse(dt.Rows[i]["notifcount"].ToString());
notification.ModuleName = dt.Rows[i]["modulename"].ToString();
}
}
}
}
}
return notificationList
}
}
Now you should use this method from whichever page you want as following.
Let say you want to use it from HomePage. So you may write following code in Page_Load event of HomePage. (I am assuming here that HomePage is a web page and it has all the controls loaded before this code gets executed).
Label userNameLabel = (Label)this.FindControl("userfullname");
var userName = userNameLabelText;
var notificationList = NotificationService.GetNotificationData(userName);
foreach(var notification in notificationList)
{
var modulename = notification.ModuleName;
var notifcount = notification.Count;
string modulebody = modulename + "Body";
string moduleLabel = modulename + "Label";
Label namebox = (Label)this.FindControl(modulename);
if (notifcount > 0)
{
namebox.Visible = true;
namebox.Text = notifcount.ToString();
this.FindControl(modulebody).Visible = true;
try
{
this.FindControl(moduleLabel).Visible = true;
}
catch
{
notifLabel.Visible = false;
}
}
else
{
namebox.Visible = false;
this.FindControl(modulebody).Visible = false;
try
{
this.FindControl(moduleLabel).Visible = false;
}
catch
{
notifLabel.Visible = false;
}
}
}
I hope this should help you resolve your issue.

How can i handle and how should i handle exception The remote server returned an error: (500) Internal Server Error?

The exception is happen most of the times but there are times it's working fine.
The exception is always the same
The remote server returned an error: (500) Internal Server Error.
Also the stacktrace is the same:
at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
at System.Net.WebClient.DownloadData(Uri address)
at System.Net.WebClient.DownloadData(String address)
at SatelliteImages.ExtractImages.ExtractDateAndTime(String baseAddress) in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\ExtractImages.cs:line 120
Line 120 is:
var temp = wc.DownloadData("/en");
The method:
public void ExtractDateAndTime(string baseAddress)
{
try
{
var wc = new WebClient();
wc.BaseAddress = baseAddress;
HtmlDocument doc = new HtmlDocument();
var temp = wc.DownloadData("/en");
doc.Load(new MemoryStream(temp));
var secTokenScript = doc.DocumentNode.Descendants()
.Where(e =>
String.Compare(e.Name, "script", true) == 0 &&
String.Compare(e.ParentNode.Name, "div", true) == 0 &&
e.InnerText.Length > 0 &&
e.InnerText.Trim().StartsWith("var region")
).FirstOrDefault().InnerText;
var securityToken = secTokenScript;
securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
foreach (var date in scriptDates)
{
DatesAndTimes.Add(date.DateString);
}
}
catch(WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
}
}
}
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
this.Init();
}
}
When I use a breakpoint on the line:
string error = reader.ReadToEnd();
I see html content and in the content I see the text:
error occurred while processing your request. Return to the homepage of Sat24.com
What I want to do is somehow when the exception happen to start over again and try the download try the method ExtractDateAndTime.
I think using a timer some how and count back showing the user something like 30 seconds and try again. Will 30 seconds try will be consider as spam/flooding in the server site ?
This is the full class code but the exception is on this method ExtractDateAndTime.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Xml;
using HtmlAgilityPack;
using System.ComponentModel;
namespace SatelliteImages
{
class ExtractImages
{
static WebClient client;
static string htmltoextract;
public static List<string> countriescodes = new List<string>();
public static List<string> countriesnames = new List<string>();
public static List<string> DatesAndTimes = new List<string>();
public static List<string> imagesUrls = new List<string>();
static string firstUrlPart = "http://www.sat24.com/image2.ashx?region=";
static string secondUrlPart = "&time=";
static string thirdUrlPart = "&ir=";
public class ProgressEventArgs : EventArgs
{
public int Percentage { get; set; }
public string StateText { get; set; }
}
public event EventHandler<ProgressEventArgs> ProgressChanged;
public void Init()
{
object obj = null;
int index = 0;
ExtractCountires();
foreach (string cc in countriescodes)
{
// raise event here
ProgressChanged?.Invoke(obj,new ProgressEventArgs{ Percentage = 100 * index / countriescodes.Count, StateText = cc });
ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
index +=1;
}
ImagesLinks();
}
public void ExtractCountires()
{
try
{
htmltoextract = "http://sat24.com/en/?ir=true";//"http://sat24.com/en/";// + regions;
client = new WebClient();
client.DownloadFile(htmltoextract, #"c:\temp\sat24.html");
client.Dispose();
string tag1 = "<li><a href=\"/en/";
string tag2 = "</a></li>";
string s = System.IO.File.ReadAllText(#"c:\temp\sat24.html");
s = s.Substring(s.IndexOf(tag1));
s = s.Substring(0, s.LastIndexOf(tag2) + tag2.ToCharArray().Length);
s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
string[] parts = s.Split(new string[] { tag1, tag2 }, StringSplitOptions.RemoveEmptyEntries);
string tag3 = "<li><ahref=\"/en/";
for (int i = 0; i < parts.Length; i++)
{
if (i == 17)
{
//break;
}
string l = "";
if (parts[i].Contains(tag3))
l = parts[i].Replace(tag3, "");
string z1 = l.Substring(0, l.IndexOf('"'));
if (z1.Contains("</ul></li><liclass="))
{
z1 = z1.Replace("</ul></li><liclass=", "af");
}
countriescodes.Add(z1);
countriescodes.GroupBy(n => n).Any(c => c.Count() > 1);
string z2 = parts[i].Substring(parts[i].LastIndexOf('>') + 1);
if (z2.Contains("&"))
{
z2 = z2.Replace("&", " & ");
}
countriesnames.Add(z2);
countriesnames.GroupBy(n => n).Any(c => c.Count() > 1);
}
}
catch (Exception e)
{
if (countriescodes.Count == 0)
{
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
Init();
}
}
}
public void ExtractDateAndTime(string baseAddress)
{
try
{
var wc = new WebClient();
wc.BaseAddress = baseAddress;
HtmlDocument doc = new HtmlDocument();
var temp = wc.DownloadData("/en");
doc.Load(new MemoryStream(temp));
var secTokenScript = doc.DocumentNode.Descendants()
.Where(e =>
String.Compare(e.Name, "script", true) == 0 &&
String.Compare(e.ParentNode.Name, "div", true) == 0 &&
e.InnerText.Length > 0 &&
e.InnerText.Trim().StartsWith("var region")
).FirstOrDefault().InnerText;
var securityToken = secTokenScript;
securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
foreach (var date in scriptDates)
{
DatesAndTimes.Add(date.DateString);
}
}
catch(WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
}
}
}
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
this.Init();
}
}
public class ScriptDate
{
public string DateString { get; set; }
public int Year
{
get
{
return Convert.ToInt32(this.DateString.Substring(0, 4));
}
}
public int Month
{
get
{
return Convert.ToInt32(this.DateString.Substring(4, 2));
}
}
public int Day
{
get
{
return Convert.ToInt32(this.DateString.Substring(6, 2));
}
}
public int Hours
{
get
{
return Convert.ToInt32(this.DateString.Substring(8, 2));
}
}
public int Minutes
{
get
{
return Convert.ToInt32(this.DateString.Substring(10, 2));
}
}
}
public void ImagesLinks()
{
int cnt = 0;
foreach (string countryCode in countriescodes)
{
cnt++;
for (; cnt < DatesAndTimes.Count(); cnt++)
{
string imageUrl = firstUrlPart + countryCode + secondUrlPart + DatesAndTimes[cnt] + thirdUrlPart + "true";
imagesUrls.Add(imageUrl);
if (cnt % 10 == 0) break;
}
}
}
}
}
What i want is in case of the exception happen to start over clean over again the whole class operation.
In Form1 i start the class operation first time once:
In top:
ExtractImages ei = new ExtractImages();
Then in constructor:
ei.Init();
The problem is this exception that sometimes happen.
You could go with something like Polly or the Transient Fault Handling Application Block to apply a retry strategy to your code.
Both packages provide multiple out-of-the-box components for various scenarios and you can always develop you own. Some of the included retry policies:
Incremental
Fixed interval
Exponential back-off
Retry
Retry for ever
Retry and wait
Wait and retry for ever
...

Multithreading issue ,Maybe a DeadLock using Foreach

Parallel.ForEach keeps on running and my program does not end. I am unable to trace where it goes after the first iteration. My guess is that gets a deadlock and keeps on doing context switching.
private void ReadInputFile()
{
var collection = new ConcurrentBag<PropertyRecord>();
var lines = System.IO.File.ReadLines(InputFileName);
int i = 0;
int RecordsCount = lines.Count();
Parallel.ForEach(lines, line =>
{
if (string.IsNullOrWhiteSpace(line))
{
return;
}
var tokens = line.Split(',');
var postalCode = tokens[0];
var country = tokens.Length > 1 ? tokens[1] : "england";
SetLabelNotifyTwoText(
string.Format(
"Reading PostCode {0} out of {1}"
i,
lines.Length));
var tempRecord = GetAllAddesses(postalCode, country);
if (tempRecord != null)
{
foreach (PropertyRecord r in tempRecord)
{
collection.Add(r);
}
}
});
}
private List<PropertyRecord> GetAllAddesses(
string postalCode,
string country = "england")
{
SetLabelNotifyText("");
progressBar1.Value = 0;
progressBar1.Update();
var records = new List<PropertyRecord>();
using (WebClient w = new WebClient())
{
var url = CreateUrl(postalCode, country);
var document = w.DownloadString(url);
var pagesCount = GetPagesCount(document);
if (pagesCount == null)
{
return null;
}
for (int i = 0; i < pagesCount; i++)
{
SetLabelNotifyText(
string.Format(
"Reading Page {0} out of {1}",
i,
pagesCount - 1));
url = CreateUrl(postalcode,country, i);
document = w.DownloadString(url);
var collection = Regex.Matches(
document,
"<div class=\"soldDetails\">(.|\\n|\\r)*?class=" +
"\"soldAddress\".*?>(?<address>.*?)(</a>|</div>)" +
"(.|\\n|\\r)*?class=\\\"noBed\\\">(?<noBed>.*?)" +
"</td>|</tbody>");
foreach (var match in collection)
{
var r = new PropertyRecord();
var bedroomCount = match.Groups["noBed"].Value;
if(!string.IsNullOrEmpty(bedroomCount))
{
r.BedroomCount = bedroomCount;
}
else
{
r.BedroomCount = "-1";
}
r.address = match.Groups["address"].Value;
var line = string.Format(
"\"{0}\",{1}",
r.address
r.BedroomCount);
OutputLines.Add(line);
Records.Add(r);
}
}
}
return Records;
}
It runs fine without Parallel.ForEach, but using Parallel.ForEach is in requirements.
I have debugged it and after returning from GetAllAdresses-method first time, Step Next button halts and it just keep on debugging in the background. It doesn't come back on any bookmark I have placed.
As you said in comments, your SetLabelNotifyText and SetLabelNotifyTwoText methods calls Control.Invoke.
For Control.Invoke to work, Main thread has to be free, but in your case you seem to block the main thread by invoking Parallel.ForEach in it.
Here is a minimal reproduction:
private void button1_Click(object sender, EventArgs e)
{
Parallel.ForEach(Enumerable.Range(1, 100), (i) =>
{
Thread.Sleep(10);//Simulate some work
this.Invoke(new Action(() => SetText(i)));
});
}
private void SetText(int i)
{
textBox1.Text = i.ToString();
}
Main thread waits for Parallel.ForEach and worker threads waits for Main thread, and thus results in deadlock.
How to fix: Don't use Invoke simply use BeginInvoke or don't block the MainThread.
If this isn't the case post sscce, that will be helpful for us
Change your code like this, to use async and await. This is the modern alternative to using BeginInvoke and other asynchronous code models.
private async Task ReadInputFile()
{
var collection = new ConcurrentBag<PropertyRecord>();
var lines = System.IO.File.ReadLines(InputFileName);
int i = 0;
int RecordsCount = lines.Count();
Parallel.ForEach(lines, line =>
{
if (string.IsNullOrWhiteSpace(line))
{
return;
}
var tokens = line.Split(',');
var postalCode = tokens[0];
var country = tokens.Length > 1 ? tokens[1] : "england";
SetLabelNotifyTwoText(
string.Format(
"Reading PostCode {0} out of {1}"
i,
lines.Length));
var tempRecord = await GetAllAddesses(postalCode, country);
if (tempRecord != null)
{
foreach (PropertyRecord r in tempRecord)
{
collection.Add(r);
}
}
});
}
private async Task<List<PropertyRecord>> GetAllAddesses(
string postalCode,
string country = "england")
{
SetLabelNotifyText("");
progressBar1.Value = 0;
progressBar1.Update();
var records = new List<PropertyRecord>();
using (WebClient w = new WebClient())
{
var url = CreateUrl(postalCode, country);
var document = await w.DownloadStringTaskAsync(url);
var pagesCount = GetPagesCount(document);
if (pagesCount == null)
{
return null;
}
for (int i = 0; i < pagesCount; i++)
{
SetLabelNotifyText(
string.Format(
"Reading Page {0} out of {1}",
i,
pagesCount - 1));
url = CreateUrl(postalcode,country, i);
document = await w.DownloadStringTaskAsync(url);
var collection = Regex.Matches(
document,
"<div class=\"soldDetails\">(.|\\n|\\r)*?class=" +
"\"soldAddress\".*?>(?<address>.*?)(</a>|</div>)" +
"(.|\\n|\\r)*?class=\\\"noBed\\\">(?<noBed>.*?)" +
"</td>|</tbody>");
foreach (var match in collection)
{
var r = new PropertyRecord();
var bedroomCount = match.Groups["noBed"].Value;
if(!string.IsNullOrEmpty(bedroomCount))
{
r.BedroomCount = bedroomCount;
}
else
{
r.BedroomCount = "-1";
}
r.address = match.Groups["address"].Value;
var line = string.Format(
"\"{0}\",{1}",
r.address
r.BedroomCount);
OutputLines.Add(line);
Records.Add(r);
}
}
}
return Records;
}
Then call it like this
ReadInputFile.Wait();
or, even better, is the caller is async,
await ReadInputFile();

Categories

Resources