C# : line = StreamReader.ReadLine <= item - c#

Working with reading a file that's formatted like this
2014/11/03 14:31:03 PID:8696 UUID:2ae855da-37d1-4a99-8510-27539afa09d0 Start E:/I3/IC/Logs/2014-11-03/SIPEngine_2.ininlog
2014/11/04 00:00:01 PID:8696 UUID:2ae855da-37d1-4a99-8510-27539afa09d0 End E:/I3/IC/Logs/2014-11-03/SIPEngine_2.ininlog
I am already stripping out the time in a variable but need to get be able to search the file for anything that is less than or equal to the value
Thanks to #dbc
Now I need to get the match on date
while (reader.next(msg, control))
{
ActiveAttributesVect_t attribs = msg.get_active_context_attributes();
ActiveAttributeValuesVect_t attribVals = msg.get_active_context_attribute_values();
int numAttribs = ((attribs != null) && (attribVals != null)) ? Math.Min(attribs.Count, attribVals.Count) : 0;
for (int i = 0; i < numAttribs; ++i)
{
if (attribVals[i].ToString().Contains(strCallID))
{
callidList.Add(msg.expand_format_message());
// Setting the date to match the log format
strCallDate = msg.timestamp().as_creator_time(header.tz_offset()).ToString().Substring(0, 10).Replace("-", "/");
strCallTime = msg.timestamp().as_creator_time(header.tz_offset()).ToString().Substring(11, 8);
Console.WriteLine("Call Time : {0}", strCallTime);
Console.WriteLine("Call Date : {0}", strCallDate);
Console.WriteLine("");
foreach (var entry in callidList)
{
Console.WriteLine(entry);
}
Console.WriteLine("");
OutputLogLinesBeforeTime(strLogDirectory, msg.timestamp().as_creator_time(header.tz_offset()), strCallTime);
}
}

You can use TimeSpan to extract and parse a time of day:
static TimeSpan? ExtractTime(string logLine)
{
var tokens = logLine.Split(new char [] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length < 2)
return null;
TimeSpan time;
if (!TimeSpan.TryParse(tokens[1], out time))
return null;
return time;
}
static DateTime? ExtractDate(string logLine)
{
var tokens = logLine.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length < 1)
return null;
DateTime date;
if (!DateTime.TryParse(tokens[0], out date))
return null;
return date;
}
static void OutputLogLinesBeforeTime(string strLogDirectory, string strLogDate, string strCallTime)
{
try
{
var time = TimeSpan.Parse(strCallTime); // Throws a format exception if invalid.
DirectoryInfo d = new DirectoryInfo(strLogDirectory + "\\" + strLogDate + "\\");
foreach (var file in d.GetFiles("*.ininlog_journal"))
{
try
{
using (Stream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sReader = new StreamReader(stream))
{
foreach (var line in sReader.EnumerateLines().Where(l => ExtractTime(l) < time))
Console.WriteLine(line);
}
}
catch (UnauthorizedAccessException ae)
{
Console.WriteLine(ae.Message);
}
catch (SystemException se)
{
Console.WriteLine(se.Message);
}
catch (ApplicationException ape)
{
Console.WriteLine(ape.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
catch (UnauthorizedAccessException ae)
{
Console.WriteLine(ae.Message);
}
catch (SystemException se)
{
Console.WriteLine(se.Message);
}
catch (ApplicationException ape)
{
Console.WriteLine(ape.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
For convenience I extracted the following:
public static class TextReaderExtensions
{
public static IEnumerable<string> ReadLines(this TextReader sReader)
{
if (sReader == null)
throw new ArgumentNullException();
string line;
while ((line = sReader.ReadLine()) != null)
yield return line;
}
}

Related

System.OutOfMemoryException in C# when Generating huge amount of byte[] objects

I'm using this code to modify a pdf tmeplate to add specific details to it,
private static byte[] GeneratePdfFromPdfFile(byte[] file, string landingPage, string code)
{
try
{
using (var ms = new MemoryStream())
{
using (var reader = new PdfReader(file))
{
using (var stamper = new PdfStamper(reader, ms))
{
string _embeddedURL = "http://" + landingPage + "/Default.aspx?code=" + code + "&m=" + eventCode18;
PdfAction act = new PdfAction(_embeddedURL);
stamper.Writer.SetOpenAction(act);
stamper.Close();
reader.Close();
return ms.ToArray();
}
}
}
}
catch(Exception ex)
{
File.WriteAllText(HttpRuntime.AppDomainAppPath + #"AttachmentException.txt", ex.Message + ex.StackTrace);
return null;
}
}
this Method is being called from this Method:
public static byte[] GenerateAttachment(AttachmentExtenstion type, string Contents, string FileName, string code, string landingPage, bool zipped, byte[] File = null)
{
byte[] finalVal = null;
try
{
switch (type)
{
case AttachmentExtenstion.PDF:
finalVal = GeneratePdfFromPdfFile(File, landingPage, code);
break;
case AttachmentExtenstion.WordX:
case AttachmentExtenstion.Word:
finalVal = GenerateWordFromDocFile(File, code, landingPage);
break;
case AttachmentExtenstion.HTML:
finalVal = GenerateHtmlFile(Contents, code, landingPage);
break;
}
return zipped ? _getZippedFile(finalVal, FileName) : finalVal;
}
catch(Exception ex)
{
return null;
}
}
and here is the main caller,
foreach (var item in Recipients)
{
//...
//....
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
}
The AttachmentGeneratorEngine.GenerateAttachment method is being called approx. 4k times, because I'm adding a specific PDF file from a PDF template for every element in my List.
recently I started having this exception:
Exception of type 'System.OutOfMemoryException' was thrown. at System.IO.MemoryStream.ToArray()
I already implemented IDisposible in the classes and and I made sure that all of them are being released.
Note: it was running before very smoothely and also I double checked the system's resources - 9 GB is used out of 16 GB, so I had enough memory available.
==========================================
Update:
Here is the code that loops through the list
public static bool ProcessGroupLaunch(string groupCode, int customerId, string UilangCode)
{
CampaignGroup cmpGList = GetCampaignGroup(groupCode, customerId, UilangCode)[0];
_campaigns = GetCampaigns(groupCode, customerId);
List<CampaignRecipientLib> Recipients = GetGroupRcipientsToLaunch(cmpGList.ID, customerId);
try
{
foreach (var item in _campaigns)
item.Details = GetCampaignDetails(item.CampaignId.Value, UilangCode);
Stopwatch stopWatch = new Stopwatch();
#region single-threaded ForEach
foreach (var item in Recipients)
{
CampaignLib _cmpTmp = _campaigns.FirstOrDefault(x => x.CampaignId.Value == item.CampaignId);
bool IncludeAttachment = _cmpTmp.IncludeAttachment ?? false;
bool IncludeAttachmentDoubleBarrel = _cmpTmp.IncludeAttachmentDoubleBarrel ?? false;
if (IncludeAttachment)
{
if (_cmpTmp.AttachmentExtension.ToLower().Equals("doc") || (_cmpTmp.AttachmentExtension.ToLower().Equals("docx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Word;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("ppt") || (_cmpTmp.AttachmentExtension.ToLower().Equals("pptx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PowePoint;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("xls") || (_cmpTmp.AttachmentExtension.ToLower().Equals("xlsx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Excel;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("pdf"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PDF;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("html"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.HTML;
}
//set "recpient" details
item.EmailFrom = _cmpTmp.EmailFromPrefix + "#" + _cmpTmp.EmailFromDomain;
item.EmailBody = GetChangedPlaceHolders((_cmpTmp.getBodybyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage)), item.ID, _cmpTmp.CustomerId.Value, _cmpTmp.CampaignId.Value);
if (item.EmailBody.Contains("[T-LandingPageLink]"))
{
//..
}
if (item.EmailBody.Contains("[T-FeedbackLink]"))
{
//..
}
if (item.EmailBody.Contains("src=\".."))
{
//..
}
//set flags to be used by the SMTP Queue and Scheduler
item.ReadyTobeSent = true;
item.PickupReady = false;
//add attachment to the recipient, if any.
if (IncludeAttachment)
{
item.AttachmentName = _cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
try
{
if (_type == AttachmentGeneratorEngine.AttachmentExtenstion.PDF || _type == AttachmentGeneratorEngine.AttachmentExtenstion.WordX || _type == AttachmentGeneratorEngine.AttachmentExtenstion.Word)
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
else item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, value, item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value);
item.AttachmentName = _cmpTmp.AttachmentZip.Value ? (_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + ".zip") :
_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
}
catch (Exception ex)
{
}
}
else
{
item.EmailAttachment = null;
item.AttachmentName = null;
}
}
#endregion
stopWatch.Stop();
bool res = WriteCampaignRecipientsLaunch(ref Recipients);
return res;
}
catch (Exception ex)
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
return false;
}
finally
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
}
}

The code is giving error at MultiSheetsPdf

This is my code which create PDF of a dwg file but it gives me error near MultiSheetPdf. Please give me the solution for same.
I thought that linking is the problem but I am not able to identify please suggest me the solution.
namespace Plottings
{
public class MultiSheetsPdf
{
private string dwgFile, pdfFile, dsdFile, outputDir;
private int sheetNum;
private IEnumerable<Layout> layouts;
private const string LOG = "publish.log";
public MultiSheetsPdfPlot(string pdfFile, IEnumerable<Layout> layouts)
{
Database db = HostApplicationServices.WorkingDatabase;
this.dwgFile = db.Filename;
this.pdfFile = pdfFile;
this.outputDir = Path.GetDirectoryName(this.pdfFile);
this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
this.layouts = layouts;
}
public void Publish()
{
if (TryCreateDSD())
{
Publisher publisher = AcAp.Publisher;
PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
publisher.PublishDsd(this.dsdFile, plotDlg);
plotDlg.Destroy();
File.Delete(this.dsdFile);
}
}
private bool TryCreateDSD()
{
using (DsdData dsd = new DsdData())
using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
{
if (dsdEntries == null || dsdEntries.Count <= 0) return false;
if (!Directory.Exists(this.outputDir))
Directory.CreateDirectory(this.outputDir);
this.sheetNum = dsdEntries.Count;
dsd.SetDsdEntryCollection(dsdEntries);
dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
dsd.SheetType = SheetType.MultiDwf;
dsd.NoOfCopies = 1;
dsd.DestinationName = this.pdfFile;
dsd.IsHomogeneous = false;
dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
PostProcessDSD(dsd);
return true;
}
}
private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
{
DsdEntryCollection entries = new DsdEntryCollection();
foreach (Layout layout in layouts)
{
DsdEntry dsdEntry = new DsdEntry();
dsdEntry.DwgName = this.dwgFile;
dsdEntry.Layout = layout.LayoutName;
dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
dsdEntry.Nps = layout.TabOrder.ToString();
entries.Add(dsdEntry);
}
return entries;
}
private void PostProcessDSD(DsdData dsd)
{
string str, newStr;
string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
dsd.WriteDsd(tmpFile);
using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
{
while (!reader.EndOfStream)
{
str = reader.ReadLine();
if (str.Contains("Has3DDWF"))
{
newStr = "Has3DDWF=0";
}
else if (str.Contains("OriginalSheetPath"))
{
newStr = "OriginalSheetPath=" + this.dwgFile;
}
else if (str.Contains("Type"))
{
newStr = "Type=6";
}
else if (str.Contains("OUT"))
{
newStr = "OUT=" + this.outputDir;
}
else if (str.Contains("IncludeLayer"))
{
newStr = "IncludeLayer=TRUE";
}
else if (str.Contains("PromptForDwfName"))
{
newStr = "PromptForDwfName=FALSE";
}
else if (str.Contains("LogFilePath"))
{
newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
}
else
{
newStr = str;
}
writer.WriteLine(newStr);
}
}
File.Delete(tmpFile);
}
[CommandMethod("PlotPdf")]
public void PlotPdf()
{
Database db = HostApplicationServices.WorkingDatabase;
short bgp = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
try
{
Application.SetSystemVariable("BACKGROUNDPLOT", 0);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
List<Layout> layouts = new List<Layout>();
DBDictionary layoutDict =
(DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
}
}
layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));
string filename = Path.ChangeExtension(db.Filename, "pdf");
MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
plotter.Publish();
tr.Commit();
}
}
catch (System.Exception e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
finally
{
Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
}
}
}
}
Here you go: (Try to note and understand the difference between your version and this version)
namespace Plottings
{
public class MultiSheetsPdf
{
private string dwgFile, pdfFile, dsdFile, outputDir;
private int sheetNum;
private IEnumerable<Layout> layouts;
private const string LOG = "publish.log";
public MultiSheetsPdf(){}
public MultiSheetsPdf(string pdfFile, IEnumerable<Layout> layouts)
{
Database db = HostApplicationServices.WorkingDatabase;
this.dwgFile = db.Filename;
this.pdfFile = pdfFile;
this.outputDir = Path.GetDirectoryName(this.pdfFile);
this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
this.layouts = layouts;
}
public void Publish()
{
if (TryCreateDSD())
{
Publisher publisher = AcAp.Publisher;
PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
publisher.PublishDsd(this.dsdFile, plotDlg);
plotDlg.Destroy();
File.Delete(this.dsdFile);
}
}
private bool TryCreateDSD()
{
using (DsdData dsd = new DsdData())
using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
{
if (dsdEntries == null || dsdEntries.Count <= 0) return false;
if (!Directory.Exists(this.outputDir))
Directory.CreateDirectory(this.outputDir);
this.sheetNum = dsdEntries.Count;
dsd.SetDsdEntryCollection(dsdEntries);
dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
dsd.SheetType = SheetType.MultiDwf;
dsd.NoOfCopies = 1;
dsd.DestinationName = this.pdfFile;
dsd.IsHomogeneous = false;
dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
PostProcessDSD(dsd);
return true;
}
}
private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
{
DsdEntryCollection entries = new DsdEntryCollection();
foreach (Layout layout in layouts)
{
DsdEntry dsdEntry = new DsdEntry();
dsdEntry.DwgName = this.dwgFile;
dsdEntry.Layout = layout.LayoutName;
dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
dsdEntry.Nps = layout.TabOrder.ToString();
entries.Add(dsdEntry);
}
return entries;
}
private void PostProcessDSD(DsdData dsd)
{
string str, newStr;
string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
dsd.WriteDsd(tmpFile);
using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
{
while (!reader.EndOfStream)
{
str = reader.ReadLine();
if (str.Contains("Has3DDWF"))
{
newStr = "Has3DDWF=0";
}
else if (str.Contains("OriginalSheetPath"))
{
newStr = "OriginalSheetPath=" + this.dwgFile;
}
else if (str.Contains("Type"))
{
newStr = "Type=6";
}
else if (str.Contains("OUT"))
{
newStr = "OUT=" + this.outputDir;
}
else if (str.Contains("IncludeLayer"))
{
newStr = "IncludeLayer=TRUE";
}
else if (str.Contains("PromptForDwfName"))
{
newStr = "PromptForDwfName=FALSE";
}
else if (str.Contains("LogFilePath"))
{
newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
}
else
{
newStr = str;
}
writer.WriteLine(newStr);
}
}
File.Delete(tmpFile);
}
[CommandMethod("PlotPdf")]
public void PlotPdf()
{
Database db = HostApplicationServices.WorkingDatabase;
short bgp = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
try
{
Application.SetSystemVariable("BACKGROUNDPLOT", 0);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
List<Layout> layouts = new List<Layout>();
DBDictionary layoutDict =
(DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
}
}
layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));
string filename = Path.ChangeExtension(db.Filename, "pdf");
MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
plotter.Publish();
tr.Commit();
}
}
catch (System.Exception e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
finally
{
Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
}
}
}
}
Heads up. The method, PostProcessDSD, tests are too generic. Client contacted me complaining that one of his files was not plotting. It was named "SOUTH". The test for "OUT" in the string caused the issue. No errors were thrown. Just a good ol' fashion mystery.
Change all tests to include the "=". ie else if (str.Contains("OUT=")) { ...

Cannot open file c#

Can someone tell me why I have this error on the below code?
The procces cannot access the file "..." beucase it's using by another procces.
I closed the first StreamReader and after, when I intialize the StreamWriter, it crashed.
private static void removeSetting(string _class)
{
try
{
string[] allSettings = new string[20];
int iSettings = 0;
using (StreamReader FILE_READER = new StreamReader("DATA.properties"))
{
string line = FILE_READER.ReadLine();
while (line != null)
{
if (!line.Equals(""))
{
allSettings[iSettings] = line;
iSettings++;
}
line = FILE_READER.ReadLine();
}
}
using (StreamWriter FILE_WRITER = new StreamWriter("DATA.properties", false))
{
for (int i = 0; i <= iSettings; i++)
{
if (!allSettings[i].Split('=')[0].Equals(_class))
{
FILE_WRITER.WriteLine('\n' + allSettings[i] + '\n');
//i--;
}
}
}
}
catch (Exception ex)
{
}
}
public static void saveSetting(string _class, string value)
{
removeSetting(_class);
try
{
StreamWriter FILE_WRITER = new StreamWriter("DATA.properties", true);
FILE_WRITER.WriteLine( _class.ToString() +'='+ value);
FILE_WRITER.Close();
}
catch (Exception ex)
{
}
}
Solution: you need find a program which open this file and kill it or reload OS.
I suggest you want change "_class=oldValue" on "_class=newValue" by using _class like this
oldText:
dog=lock
cat=bob
use saveSetting(dog, fork)
newText:
cat=bob
dog=fork
you can use this method
private static void removeSetting(string _class,string value)
{
try
{
//read all lines from file
string[] allSettings = File.ReadAllLines("DATA.properties");
//divide string on string[] by '='
List<List<string>> strings = allSettings.Select(x => x.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries).ToList()).ToList();
//find all lines where first element equals _class
List<List<string>> result = strings.Where(x => x.First().Equals(_class)).Select(x=>new List<string>{_class, value}).ToList();
// convert string[] => string
string[] secondResult = result.Select(x => String.Join("=",x.ToArray())).ToArray();
List<List<string>> otherResult = strings.Where(x => !x.First().Equals(_class)).Select(x => x).ToList();
string[] firstResult = otherResult.Select(x => String.Join("=", x.ToArray())).ToArray();
//wrtie all lines in file
File.WriteAllLines("DATA.properties",firstResult);
File.AppendAllLines("DATA.properties", secondResult);
}
catch (Exception ex)
{
}
}

CPU utilisation goes to 100% while processing a text file

I have a master account file having more than 300000 records. This file is having Office, FA, UUID fields along with other fields. We have a webservice which retuns currently enrolled offices for pilot.
I need to generate a output file with unique UUIDs from master account file which are part of pilot. The below is my code.
public class Job
{
static Dictionary<string, string> UUIDOfficeFA = new Dictionary<string, string>();
static Dictionary<string, string> UUIDs = new Dictionary<string, string>();
static string PilotOfficeList = string.Empty;
/// <summary>
///
/// </summary>
public void RunJob()
{
try
{
DirectoryInfo directoryInfo = new DirectoryInfo(ConfigurationSettings.AppSettings["AccountFileFolder"]);
if (directoryInfo != null || directoryInfo.Exists == false)
{
FileInfo[] files = directoryInfo.GetFiles();
DateTime lastWrite = DateTime.MinValue;
FileInfo lastWritenFile = null;
foreach (FileInfo file in files)
{
if (file.LastWriteTime > lastWrite)
{
lastWrite = file.LastWriteTime;
lastWritenFile = file;
}
}
if (lastWritenFile != null)
{
if (RetrieveUUIDs(lastWritenFile))
{
WriteFile();
}
}
else
{
throw new Exception("No matching account file found for processing");
}
}
}
catch (Exception ex)
{
throw ex;
}
}
static void WriteFile()
{
try
{
string FileName = "Testfile_" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
string Path = ConfigurationSettings.AppSettings["TestFolder"] + #"\" + FileName;
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> kvp in UUIDs)
{
sb.AppendLine(kvp.Value);
}
using (StreamWriter writer = File.AppendText(Path))
{
writer.Write(sb.ToString());
writer.Flush();
}
}
catch (Exception ex)
{
throw ex;
}
}
static bool RetrieveUUIDs(FileInfo file)
{
try
{
using (StreamReader sr = file.OpenText())
{
string accountFileData = null;
accountFileData = sr.ReadToEnd();
string[] str = accountFileData.Trim().Split(new string[] { "\n" }, StringSplitOptions.None);
List<string> AccountInfo = new List<string>(str);
if (AccountInfo.Count > 0)
{
TestWebservice client = new TestWebservice();
GetBrancheListRequest request = new GetBrancheListRequest();
GetBrancheListResponse response =client.GetBrancheList(request);
if (response != null)
{
PilotOfficeList = response.GetBrancheListResult;
if (string.IsNullOrEmpty(PilotOfficeList))
{
throw new Exception("No branch is enrolled for pilot");
}
}
}
foreach (string accountInfo in AccountInfo)
{
RetrieveUUID(accountInfo);
}
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
private static void RetrieveUUID(string line)
{
try
{
string UUID = line.Substring(2, 50).Trim();
string Office = line.Substring(444, 3).Trim();
string FA = line.Substring(447, 3).Trim();
if (!string.IsNullOrEmpty(PilotOfficeList))
{
if (!string.IsNullOrEmpty(UUID) || !string.IsNullOrEmpty(Office))
{
if (PilotOfficeList.IndexOf(Office) > -1)
{
if (!UUIDOfficeFA.ContainsKey(UUID + Office + FA))
{
UUIDOfficeFA.Add(UUID + Office + FA, UUID + Office + FA);
if (!UUIDs.ContainsKey(UUID))
{
UUIDs.Add(UUID, UUID);
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
The issue is when this program runs the CPU utilisation goes to 100%. Although entire job completes within 2 minutes but i can't move this on server beacuse it might cause issue for other apps. Please suggest how i can optimize this so that CPU doesn't goes to 100%.
Thank you so much for your help in prior.
Note- It appears that following are few major CPU utilization points
1-
accountFileData = sr.ReadToEnd();
2-
string[] str = accountFileData.Trim().Split(new string[] { "\n" }, StringSplitOptions.None);
3-
foreach (string accountInfo in AccountInfo)
{
RetrieveUUID(accountInfo);
}

MySQL OdbcCommand commands sometimes hangs?

I am running a loop in C# that reads a file and make updates to the MySQL database with MySQL ODBC 5.1 driver in a Windows 8 64-bit environment.
The operations is simple
Count +1
See if file exists
Load XML file(XDocument)
Fetch data from XDocument
Open ODBCConnection
Run a couple of Stored Procedures against the MySQL database to store data
Close ODBCConnection
The problem is that after a while it will hang on for example a OdbcCommand.ExecuteNonQuery. It is not always the same SP that it will hang on?
This is a real problem, I need to loop 60 000 files but it only last around 1000 at a time.
Edit 1:
The problem seemse to accure here hever time :
public bool addPublisherToGame(int inPublisherId, int inGameId)
{
string sqlStr;
OdbcCommand commandObj;
try
{
sqlStr = "INSERT INTO games_publisher_binder (gameId, publisherId) VALUE(?,?)";
commandObj = new OdbcCommand(sqlStr, mainConnection);
commandObj.Parameters.Add("#gameId", OdbcType.Int).Value = inGameId;
commandObj.Parameters.Add("#publisherId", OdbcType.Int).Value = inPublisherId;
if (Convert.ToInt32(executeNonQuery(commandObj)) > 0)
return true;
else
return false;
}
catch (Exception ex)
{
throw (loggErrorMessage(this.ToString(), "addPublisherToGame", ex, -1, "", ""));
}
finally
{
}
}
protected object executeNonQuery(OdbcCommand inCommandObj)
{
try
{
//FileStream file = new FileStream("d:\\test.txt", FileMode.Append, FileAccess.Write);
//System.IO.StreamWriter stream = new System.IO.StreamWriter(file);
//stream.WriteLine(DateTime.Now.ToString() + " - " + inCommandObj.CommandText);
//stream.Close();
//file.Close();
//mainConnection.Open();
return inCommandObj.ExecuteNonQuery();
}
catch (Exception ex)
{
throw (ex);
}
}
I can see that the in parameters is correct
The open and close of the connection is done in a top method for ever loop (with finally).
Edit 2:
This is the method that will extract the information and save to database :
public Boolean addBoardgameToDatabase(XElement boardgame, GameFactory gameFactory)
{
int incomingGameId = -1;
XElement tmpElement;
string primaryName = string.Empty;
List<string> names = new List<string>();
GameStorage externalGameStorage;
int retry = 3;
try
{
if (boardgame.FirstAttribute != null &&
boardgame.FirstAttribute.Value != null)
{
while (retry > -1)
{
try
{
incomingGameId = int.Parse(boardgame.FirstAttribute.Value);
#region Find primary name
tmpElement = boardgame.Elements("name").Where(c => c.Attribute("primary") != null).FirstOrDefault(a => a.Attribute("primary").Value.Equals("true"));
if (tmpElement != null)
primaryName = tmpElement.Value;
else
return false;
#endregion
externalGameStorage = new GameStorage(incomingGameId,
primaryName,
string.Empty,
getDateTime("1/1/" + boardgame.Element("yearpublished").Value),
getInteger(boardgame.Element("minplayers").Value),
getInteger(boardgame.Element("maxplayers").Value),
boardgame.Element("playingtime").Value,
0, 0, false);
gameFactory.updateGame(externalGameStorage);
gameFactory.updateGameGrade(incomingGameId);
gameFactory.removeDesignersFromGame(externalGameStorage.id);
foreach (XElement designer in boardgame.Elements("boardgamedesigner"))
{
gameFactory.updateDesigner(int.Parse(designer.FirstAttribute.Value), designer.Value);
gameFactory.addDesignerToGame(int.Parse(designer.FirstAttribute.Value), externalGameStorage.id);
}
gameFactory.removePublishersFromGame(externalGameStorage.id);
foreach (XElement publisher in boardgame.Elements("boardgamepublisher"))
{
gameFactory.updatePublisher(int.Parse(publisher.FirstAttribute.Value), publisher.Value, string.Empty);
gameFactory.addPublisherToGame(int.Parse(publisher.FirstAttribute.Value), externalGameStorage.id);
}
foreach (XElement element in boardgame.Elements("name").Where(c => c.Attribute("primary") == null))
names.Add(element.Value);
gameFactory.removeGameNames(incomingGameId);
foreach (string name in names)
if (name != null && name.Length > 0)
gameFactory.addGameName(incomingGameId, name);
return true;
}
catch (Exception)
{
retry--;
if (retry < 0)
return false;
}
}
}
return false;
}
catch (Exception ex)
{
throw (new Exception(this.ToString() + ".addBoardgameToDatabase : " + ex.Message, ex));
}
}
And then we got one step higher, the method that will trigger addBoardgameToDatabase :
private void StartThreadToHandleXmlFile(int gameId)
{
FileInfo fileInfo;
XDocument xmlDoc;
Boolean gameAdded = false;
GameFactory gameFactory = new GameFactory();
try
{
fileInfo = new FileInfo(_directory + "\\" + gameId.ToString() + ".xml");
if (fileInfo.Exists)
{
xmlDoc = XDocument.Load(fileInfo.FullName);
if (addBoardgameToDatabase(xmlDoc.Element("boardgames").Element("boardgame"), gameFactory))
{
gameAdded = true;
fileInfo.Delete();
}
else
return;
}
if (!gameAdded)
{
gameFactory.InactivateGame(gameId);
fileInfo.Delete();
}
}
catch (Exception)
{ throw; }
finally
{
if(gameFactory != null)
gameFactory.CloseConnection();
}
}
And then finally the top level :
public void UpdateGames(string directory)
{
DirectoryInfo dirInfo;
FileInfo fileInfo;
Thread thread;
int gameIdToStartOn = 1;
dirInfo = new DirectoryInfo(directory);
if(dirInfo.Exists)
{
_directory = directory;
fileInfo = dirInfo.GetFiles("*.xml").OrderBy(c=> int.Parse(c.Name.Replace(".xml",""))).FirstOrDefault();
gameIdToStartOn = int.Parse(fileInfo.Name.Replace(".xml", ""));
for (int gameId = gameIdToStartOn; gameId < 500000; gameId++)
{
try
{ StartThreadToHandleXmlFile(gameId); }
catch(Exception){}
}
}
}
Use SQL connection pooling by adding "Pooling=true" to your connectionstring.
Make sure you properly close the connection AND the file.
You can create one large query and execute it only once, I think it is a lot faster then 60.000 loose queries!
Can you show a bit of your code?

Categories

Resources