Exception of type 'System.StackOverflowException' [duplicate] - c#

This question already has answers here:
How to debug a stackoverflowexception in .NET
(11 answers)
Closed 1 year ago.
My program throws this exception: System.StackOverflowException: 'Exception_WasThrown'
Details:
System.StackOverflowException HResult=0x800703E9
Message=Exception_WasThrown
I'm assembling an object to print a report, when I bring 37999 data I have to group them and get the requested information, but in the middle of the way the unformed error above pops.
Here is the code of the method where the error happens.
private List<RelFilmesSeries> RetornaListaFilmes(List<RelFilmesSeries> dados, List<RelFilmesSe`enter code here`ries> filmes, bool boolOnePaises)
{
{
Utils Utils = new Utils();
RelFilmesSeries filme = new RelFilmesSeries();
GroupRightCountries GroupRightCountries = new GroupRightCountries();
List<GroupRightCountries> ListGroupRightCountries = new List<GroupRightCountries>();
List<string> Direitos = new List<string>();
var result = "";
foreach (var item in dados)
{
if (dados.Count != 0)
{
filme = new RelFilmesSeries();
filme.titulo_original = item.titulo_ingles;
filme.direcao = item.direcao;
filme.producao = item.producao != null ? item.producao.Substring(0, Math.Min(item.producao.Length, 150)) + "..." : "";
filme.elenco = item.elenco != null ? item.elenco.Substring(0, Math.Min(item.elenco.Length, 150)) + "..." : "";
filme.generos_nomes = item.generos_nomes;
filme.pais_producao = item.pais_producao;
filme.sinopse_ingles = item.sinopse_ingles;
//filme.status = RemoveStringsIguais(dados[0].status.Split(','));
filme.caminho_poster_url = Utils.ConvertImageURLToBase64(dados[0].caminho_poster_url);
filme.titulo_original = item.titulo_original;
var dadosDireito = dados
.Where(x => string.IsNullOrEmpty(x.titulo_original)
|| x.titulo_original == item.titulo_original).ToList();
if (boolOnePaises)
{
//Pega os direitos relacionados ao filme
for (int i = 0; i < dadosDireito.Count; i++)
{
GroupRightCountries = new GroupRightCountries();
if (dadosDireito[i].titulo_original == item.titulo_original && !Direitos.Contains(dadosDireito[i].direito))
{
GroupRightCountries.Direito = dadosDireito[i].direito;
Direitos.Add(dadosDireito[i].direito);
}
if (GroupRightCountries.Direito != null)
{
filme.GroupRightCountries.Add(GroupRightCountries);
}
}
}
else if (!boolOnePaises)
{
//Pega os direitos relacionados ao filme
for (int i = 0; i < dadosDireito.Count; i++)
{
GroupRightCountries = new GroupRightCountries();
if (filme.GroupRightCountries.Count > 0)
{
if (filme.GroupRightCountries.Where(x => x.Direito== dadosDireito[i].direito).ToList().Count == 0)
{
if (filme.GroupRightCountries.Count == 0)
{
if (dadosDireito[i].titulo_original == item.titulo_original)
{
GroupRightCountries.Direito = dadosDireito[i].direito;
//Pega os paises que são relacionados ao direito
for (int j = 0; j < dadosDireito.Count; j++)
{
if (dadosDireito[j].direito == dadosDireito[i].direito)
{
if (GroupRightCountries.Direito == null)
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
else
{
if (!GroupRightCountries.Paises.Contains(dadosDireito[j].Pais_regiao))
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
}
}
}
}
if (GroupRightCountries.Direito != null)
{
filme.GroupRightCountries.Add(GroupRightCountries);
}
}
else if (filme.GroupRightCountries.Where(x => x.Direito == dadosDireito[i].direito).ToList().Count == 0)
{
if (dadosDireito[i].titulo_original == item.titulo_original)
{
GroupRightCountries.Direito = dadosDireito[i].direito;
//Pega os paises que são relacionados ao direito
for (int j = 0; j < dadosDireito.Count; j++)
{
if (dadosDireito[j].direito == dadosDireito[i].direito)
{
if (GroupRightCountries.Direito == null)
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
else
{
if (!GroupRightCountries.Paises.Contains(dadosDireito[j].Pais_regiao))
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
}
}
}
}
if (GroupRightCountries.Direito != null)
{
filme.GroupRightCountries.Add(GroupRightCountries);
}
}
}
}
else
{
if (filme.GroupRightCountries.Count == 0)
{
if (dadosDireito[i].titulo_original == item.titulo_original)
{
GroupRightCountries.Direito = dadosDireito[i].direito;
//Pega os paises que são relacionados ao direito
for (int j = 0; j < dadosDireito.Count; j++)
{
if (dadosDireito[j].direito == dadosDireito[i].direito)
{
if (GroupRightCountries.Direito == null)
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
else
{
if (!GroupRightCountries.Paises.Contains(dadosDireito[j].Pais_regiao))
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
}
}
}
}
if (GroupRightCountries.Direito != null)
{
filme.GroupRightCountries.Add(GroupRightCountries);
}
}
else if (filme.GroupRightCountries.Where(x => x.Direito == dadosDireito[i].direito).ToList().Count == 0)
{
if (dadosDireito[i].direito == item.direito && dadosDireito[i].titulo_original == item.titulo_original)
{
GroupRightCountries.Direito = dadosDireito[i].direito;
//Pega os paises que são relacionados ao direito
for (int j = 0; j < dadosDireito.Count; j++)
{
if (dadosDireito[j].direito == dadosDireito[i].direito)
{
if (GroupRightCountries.Direito == null)
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
else
{
if (!GroupRightCountries.Paises.Contains(dadosDireito[j].Pais_regiao))
{
GroupRightCountries.Paises.Add(dadosDireito[j].Pais_regiao);
}
}
}
}
}
if (GroupRightCountries.Direito != null)
{
filme.GroupRightCountries.Add(GroupRightCountries);
}
}
}
}
}
//filme.direito = boolOnePaises == false
// ? ConcatenaDireitos(dados, "", dados[0].titulo_original, dados[0].direito)
// : ConcatenaDireitos(dados, "", dados[0].titulo_original);
Direitos = new List<string>();
filmes.Add(filme);
dados.RemoveAll(x => x.titulo_original == item.titulo_original);
if (dados.Count != 0)
{
return RetornaListaFilmes(dados, filmes, boolOnePaises);
}
else
{
break;
}
}
}
//Fase 2 concatena os dados de direito com os paises;
List<RelFilmesSeries> ListResultFilmes = new List<RelFilmesSeries>();
foreach (var item in filmes)
{
result = "";
filme = new RelFilmesSeries();
filme.titulo_original = item.titulo_ingles;
filme.direcao = item.direcao;
filme.producao = item.producao;
filme.elenco = item.elenco;
filme.generos_nomes = item.generos_nomes;
filme.pais_producao = item.pais_producao;
filme.sinopse_ingles = item.sinopse_ingles;
//filme.status = RemoveStringsIguais(dados[0].status.Split(','));
filme.caminho_poster_url = item.caminho_poster_url; //Utils.ConvertImageURLToBase64(dados[0].caminho_poster_url);
filme.titulo_original = item.titulo_original;
if (boolOnePaises)
{
//Pega os direitos relacionados ao filme e concatena
for (int i = 0; i < item.GroupRightCountries.Count; i++)
{
if (result == "")
{
result = item.GroupRightCountries[i].Direito;
}
else
{
result += ", " + item.GroupRightCountries[i].Direito;
}
}
filme.direito = result;
}
else if (!boolOnePaises)
{
//Pega os direitos e os paises relacionados ao filme e concatena
for (int i = 0; i < item.GroupRightCountries.Count; i++)
{
if (result == "")
{
result = item.GroupRightCountries[i].Direito + ": [ ";
for (int j = 0; j < item.GroupRightCountries[i].Paises.Count; j++)
{
if (j < item.GroupRightCountries[i].Paises.Count - 1)
{
result += item.GroupRightCountries[i].Paises[j] + ", ";
}
else
{
result += item.GroupRightCountries[i].Paises[j] + " ] ";
}
}
}
else
{
result += item.GroupRightCountries[i].Direito + ": [ ";
for (int j = 0; j < item.GroupRightCountries[i].Paises.Count; j++)
{
if (j < item.GroupRightCountries[i].Paises.Count - 1)
{
result += item.GroupRightCountries[i].Paises[j] + ", ";
}
else
{
result += item.GroupRightCountries[i].Paises[j] + " ] ";
}
}
}
}
filme.direito += result;
}
ListResultFilmes.Add(filme);
}
return ListResultFilmes;
}
catch (Exception e)
{
throw e;
}
}

You have some recursion in your code:
if (dados.Count != 0)
{
return RetornaListaFilmes(dados, filmes, boolOnePaises);
}
The StackOverflowException would suggest that this recursion is happening endlessly. Probably you are recursing without removing any items from the list, so each call recurses in the same way until the exception occurs. (EDIT rereading your question and code, it could simply be that you're trying to recurse 37999 times, once for each item in the list...)
It's not clear from your question what your intent is, but from the shape of your code it seems likely that you should be either using recursion or looping through your list, not both.
(There are a number of other issues with your code - for example, the check if (dados.Count != 0) is redundant, as you will only reach that line if there is an item in the list to enumerate.)

I managed to solve the problem, removed the recursion and added
an if condition:
if (filmes.Where(x => x.titulo_original == item.titulo_original).ToList().Count == 0)
{
}

Related

Print Nested Objects in 2D

I have a list of objects with lists of child objects which also have lists of child objects, etc. Here is a simplification with objects A and H:
I would like to print them out in a 2D array, like so:
But I keep getting this:
I'm using recursion for the first time, so tracking which row I'm on for which nested level is difficult. The code I'm using is cluttered with a bunch of carve-outs, so I'm hesitant to post it.
Does anyone have some pseudo-code that could help me fix my alignment issues?
List<int> levelStart = new List<int>();
List<int> levelEnd = new List<int>();
int tempEnding = 0;
public void propertyValues2(Object inv, object[,] dataTest)
{
Type objType = inv.GetType();
PropertyInfo[] properties = inv.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
DisplayNameAttribute DNA = (DisplayNameAttribute)property.GetCustomAttributes(typeof(DisplayNameAttribute), false).FirstOrDefault();
object propValue = property.GetValue(inv, null);
var elems = propValue as System.Collections.IList;
if (exportAll == true || exportColumns.Contains(DNA.DisplayName))
{
if (elems != null && elems.Count != 0)
{
foreach (var item in elems)
{
if (!item.GetType().FullName.StartsWith("System.String"))
{
levelStart.Add(levelStart[levelStart.Count-1]);
propertyValues2(item, dataTest);
levelStart.RemoveAt(levelStart.Count - 1);
}
else if (exportColumns.Contains(DNA.DisplayName) || exportAll == true)
{
int counter = tempEnding;
if (dataTest[tempEnding, columnIDs[DNA.DisplayName]] != null)
{
//dataRow = level[0];
for (int di = tempEnding; dataTest[di, columnIDs[DNA.DisplayName]] != null; di++)
{
tempEnding = di+1;
}
}
dataTest[tempEnding, columnIDs[DNA.DisplayName]] = item;
if (tempEnding > endingRow)
{
endingRow = tempEnding;
}
}
}
tempEnding = levelStart[levelStart.Count-1];
//dataRow = level[0];//level[0]
}
else if (elems != null && elems.Count == 0)
{
int i = 0;
}
else if (propValue != null && propValue.ToString() != "")
{
//dataRow = level[0];//level[0]
//int counter = level[level.Count-1];
if(DNA.DisplayName == "Procedure" || DNA.DisplayName == "Revenue Code")
{
if (columnIDs.Keys.Contains("Procedure") && columnIDs.Keys.Contains("Revenue Code"))
{
for (int di = tempEnding; dataTest[di, columnIDs["Procedure"]] != null || dataTest[di, columnIDs["Revenue Code"]] != null; di++)
{
tempEnding++;
}
}
}
if (dataTest[tempEnding, columnIDs[DNA.DisplayName]] != null)
{
for (int di = tempEnding; dataTest[di, columnIDs[DNA.DisplayName]] != null; di++)
{
tempEnding++;
}
}
dataTest[tempEnding, columnIDs[DNA.DisplayName]] = propValue.ToString();
if (tempEnding > endingRow)
{
endingRow = tempEnding;
}
}
}
else if (elems != null && elems.Count != 0)
{
levelStart.Add(levelStart[levelStart.Count - 1]);
foreach (var item in elems)
{
if (!item.GetType().FullName.StartsWith("System.String"))
{
propertyValues2(item, dataTest);
}
else if (exportColumns.Contains(DNA.DisplayName) || exportAll == true)
{
int counter = levelStart[levelStart.Count - 1];
if (dataTest[counter, columnIDs[DNA.DisplayName]] != null)//level[level.Count - 1]
{
for (int di = levelStart[0]; dataTest[di, columnIDs[DNA.DisplayName]] != null; di++)
{
counter++;//level[level.Count - 1]
}
}
dataTest[counter, columnIDs[DNA.DisplayName]] = item;//level[level.Count - 1]
if (endingRow < counter)
{
endingRow = counter;
}
}
levelStart[levelStart.Count - 1] = endingRow + 1;
}
levelStart.RemoveAt(levelStart.Count - 1);
}
}
foreach (string columnToCopy in columnsToCopy)
{
if (exportColumns.Contains(columnToCopy) || exportAll == true)
{
for (int i = levelStart[0] + 1; i <= endingRow; i++)//level[0]
{
dataTest[i, columnIDs[columnToCopy]] = dataTest[i - 1, columnIDs[columnToCopy]];
}
}
}
}
Array Structure:
Here is the code I worked on yesterday. It seems to work in my test runs, but I will continue testing today. It has too many row changes while printing for me to keep track of, so I'm not completely sure it always prints correctly:
int startInvoice = 1;
List<int> levelStart = new List<int> { 1 };
List<int> levelEnd = new List<int> { 1 };
List<int> maxWithinLevel = new List<int> { 0 };
int depth = 0;
public int propertyValues3(Object inv, object[,] dataTest)
{
//int maxWithinLevel = 0;
PropertyInfo[] properties = inv.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
DisplayNameAttribute DNA = (DisplayNameAttribute)property.GetCustomAttributes(typeof(DisplayNameAttribute), false).FirstOrDefault();
object propValue = property.GetValue(inv, null);
var elems = propValue as System.Collections.IList;
//if its a list
if (elems != null && elems.Count != 0)
{
levelStart.Add(levelEnd[levelEnd.Count - 1]);
levelEnd.Add(levelStart[levelStart.Count - 1]);
foreach (var item in elems)
{
//if its a class
if (!item.GetType().FullName.StartsWith("System.String"))
{
depth++;
levelStart[levelStart.Count-1] = propertyValues3(item, dataTest);
depth--;
if (levelEnd[levelEnd.Count - 1] < levelStart[levelStart.Count - 1])
{
levelEnd[levelEnd.Count - 1] = levelStart[levelStart.Count - 1];
}
}
//if its a string
else
{
if (dataTest[levelEnd[levelEnd.Count - 1], columnIDs[DNA.DisplayName]] != null)
{
for (int i = levelEnd[levelEnd.Count - 1]; dataTest[i, columnIDs[DNA.DisplayName]] != null; i++)
{
levelEnd[levelEnd.Count - 1] = i + 1;
}
}
dataTest[levelEnd[levelEnd.Count - 1], columnIDs[DNA.DisplayName]] = item; //legit
if (levelEnd[levelEnd.Count - 1] > endingRow)//legit
{
endingRow = levelEnd[levelEnd.Count - 1];
}
}
}
levelStart.RemoveAt(levelStart.Count - 1);
//if (!elems[0].GetType().FullName.StartsWith("System.String"))
if(depth>0)
{
maxWithinLevel.Add(levelEnd[levelEnd.Count - 1]);
}
levelEnd.RemoveAt(levelEnd.Count - 1);
}
//if elems is empty
else if (elems != null && elems.Count == 0)
{
int i = 0;
}
//if it's not a list
else if (propValue != null && propValue.ToString() != "")
{
//handle procedure/revcode
if (DNA.DisplayName == "Procedure" || DNA.DisplayName == "Revenue Code")
{
if (columnIDs.Keys.Contains("Procedure") && columnIDs.Keys.Contains("Revenue Code"))
{
for (int i = levelEnd[levelEnd.Count - 1]; dataTest[i, columnIDs["Procedure"]] != null || dataTest[i, columnIDs["Revenue Code"]] != null; i++)
{
levelEnd[levelEnd.Count - 1]++;
}
}
}
if (dataTest[levelEnd[levelEnd.Count - 1], columnIDs[DNA.DisplayName]] != null)
{
for (int i = levelEnd[levelEnd.Count - 1]; dataTest[i, columnIDs[DNA.DisplayName]] != null; i++)//legit
{
levelEnd[levelEnd.Count - 1]++;
}
}
dataTest[levelEnd[levelEnd.Count - 1], columnIDs[DNA.DisplayName]] = propValue.ToString();//level[level.Count - 1]
if (levelEnd[levelEnd.Count - 1] > endingRow)
{
endingRow = levelEnd[levelEnd.Count - 1];
}
}
}
if (levelStart.Count==0 || levelStart.Max() < maxWithinLevel.Max())
{
return maxWithinLevel.Max() + 1;
}
else return levelStart.Max();
}

How to make my code evaluate the whole arithmetic expression?

I am trying to make a string calculator, it works fine with two numbers but I always encounter a problem when evaluating multiple operations:
7*2+4=
Also can you help me with my multiplication and division code. I don't understand why it prints 0 even with just two numbers(7*5)
using System;
using System.Text.RegularExpressions;
namespace Sariling_Calcu
{
class Program
{
private static string exp;
private static int[] i = new int[1000];
private static char[] oper = new char[10];
private static int cntr2;
private static int result;
private static int pluscount;
private static int subcount;
private static int mulcount;
private static int divcount;
static void getNum()
{
string[] strNum = (Regex.Split(exp, #"\D+"));
for (int cntr = 0; cntr < exp.Length; cntr++)
{
foreach (string item in strNum)
{
if (!string.IsNullOrEmpty(item))
{
i[cntr] = int.Parse(item);
cntr += 1;
}
}
}
}
static void counter()
{
for (int cntr = 0; cntr < exp.Length; cntr++)
{
if (exp[cntr] == '+')
{
pluscount++;
}
else if (exp[cntr] == '-')
{
subcount++;
}
else if (exp[cntr] == '*')
{
mulcount++;
}
else if (exp[cntr] == '/')
{
divcount--;
}
}
}
static void oprtr()
{
for (int cntr = 0; cntr < exp.Length; cntr++)
{
if (exp[cntr] != '1'
&& exp[cntr] != '2'
&& exp[cntr] != '3'
&& exp[cntr] != '4'
&& exp[cntr] != '5'
&& exp[cntr] != '6'
&& exp[cntr] != '7'
&& exp[cntr] != '8'
&& exp[cntr] != '9')
{
if (exp[cntr] == '+')
{
result += i[cntr2];
cntr2 += 1;
pluscount--;
if (pluscount == 0 && subcount == 0 && mulcount==0 && divcount==0)
{
cntr2 += 3;
result += i[cntr2];
}
}
else if (exp[cntr] == '-')
{
result -= i[cntr2];
cntr2 += 1;
subcount--;
result = -result;
if (pluscount == 0 && subcount == 0 && mulcount == 0 && divcount == 0)
{
cntr2 += 3;
result -= i[cntr2];
}
}
else if (exp[cntr] == '*')
{
if (result == 0)
{
result += 1;
}
result *= i[cntr2];
cntr2 += 1;
mulcount--;
if (pluscount == 0 && subcount == 0 && mulcount == 0 && divcount == 0)
{
cntr2 += 3;
result *= i[cntr2];
}
}
else if (exp[cntr] == '/')
{
if (result == 0)
{
result += 1;
}
result /= i[cntr2];
cntr2 += 1;
divcount--;
if (pluscount == 0 && subcount == 0 && mulcount == 0 && divcount == 0)
{
cntr2 += 3;
result /= i[cntr2];
}
}
}
}
}
static void Main(string[] args)
{
Console.Write("Expression: ");
exp = Console.ReadLine();
counter();
getNum();
oprtr();
Console.Write("Answer: \n" + result);
Console.ReadLine();
}
}
}
you could use LINQ to reduce your code to a few lines but looks like its a school assignment where you would have to go with Arrays and loops.
I have tried to refine your code a bit and did a few fixes, change getNum(), counter() and oprtr() methods as below and let me know if it works, then I would add some comments in the code to explain changes I made.
static void getNum()
{
string[] strNum = (Regex.Split(exp, #"\D+"));
for (int cntr = 0; cntr < strNum.Length; cntr++)
{
if (!string.IsNullOrEmpty(strNum[cntr]))
{
i[cntr] = int.Parse(strNum[cntr]);
}
}
}
static void counter()
{
cntr2 = 0;
for (int cntr = 0; cntr < exp.Length; cntr++)
{
if (exp[cntr] == '+')
{
oper[cntr2] = '+';
cntr2++;
}
else if (exp[cntr] == '-')
{
oper[cntr2] = '-';
cntr2++;
}
else if (exp[cntr] == '*')
{
oper[cntr2] = '*';
cntr2++;
}
else if (exp[cntr] == '/')
{
oper[cntr2] = '/';
cntr2++;
}
}
}
static void oprtr()
{
result = i[0];
cntr2 = 1;
for (int cntr = 0; cntr < oper.Length; cntr++)
{
if (oper[cntr] == '+')
{
result += i[cntr2];
}
else if (oper[cntr] == '-')
{
result -= i[cntr2];
}
else if (oper[cntr] == '*')
{
result *= i[cntr2];
}
else if (oper[cntr] == '/')
{
if (i[cntr2] == 0)
{
throw new DivideByZeroException();
}
result /= i[cntr2];
}
cntr2 += 1;
}
}

Adding algebraic X notation

I am trying for the last few hours on how to parse a string with algebric notation.
For example if I have the input:
X+8X-21X+21X+16
The output should be:
9X+16
so far if I tried to see if there exists a number behind X and tried many cases, however I keep on getting an index out of bounds error, and rightufully so. Any suggestions on how to fix it?
int getXPosition= LHSString.IndexOf("X");
int noOfXs = LHSString.Split('X').Length - 1;
int XCount = 0;
if (getXPosition > -1)
{
while (XCount <= noOfXs)
{
int posX = getPositionX(s);
Regex noBeforeX = new Regex(#"\d+");
if ((posX - 1) > -1 && noBeforeX.IsMatch(LHSString.Substring(posX-1,1)))
{
string getNumber = LHSString.Substring(posX-1, 1);
sum += Convert.ToInt32(getNumber);
}
if ((posX - 2) > -1 && noBeforeX.IsMatch(LHSString.Substring(posX - 2, 1)))
{
string gotNumber = LHSString.Substring(posX - 1, 1);
int Number=Convert.ToInt32(gotNumber);
sum += Number;
}
XCount++;
s = s.Substring(posX + 1);
}
}
I would use a more maintainable approach. separate different code parts and use collection of class that will represent the "part" in the algebraic equation.
here is my suggestion:
class Program
{
static void Main(string[] args)
{
string[] operators = { "+", "-", "/", "*" };
string test = "X+8X-21X+21X+16";
int locationcounter = 0;
string part = string.Empty;
List<Part> partsList = new List<Part>();
for (int i = 0; i < test.Length; i++)
{
if (operators.Contains(test[i].ToString()))
{
var operatorbeofore = (partsList.Count <= 0 ? "" : partsList[partsList.Count - 1].OperatorAfter);
partsList.Add(new Part(part, operatorbeofore, test[i].ToString(), locationcounter));
locationcounter++;
part = string.Empty;
}
else
{
part += test[i].ToString();
}
}
// last part that remain
if (part != string.Empty)
{
partsList.Add(new Part(part, partsList[partsList.Count() - 1].OperatorAfter, "", locationcounter++));
}
// output
Console.WriteLine(GetResultOutput(partsList));
Console.ReadLine();
}
private static string GetResultOutput(List<Part> algebraicexpression)
{
// reduce all vars
var vars = algebraicexpression.Where(x => x.IsVar).OrderBy(x => x.locationInEqution).ToList();
int lastVarResult = 0;
int varResult = 0;
if (vars.Count() > 1)
{
lastVarResult = GetCalculation(vars[0].Value, vars[1].Value, vars[1].OperatorBefore);
for (int i = 2; i < vars.Count(); i++)
{
varResult = GetCalculation(lastVarResult, vars[i].Value, vars[i].OperatorBefore);
lastVarResult = varResult;
}
}
else if (vars.Count() == 1)
{
lastVarResult = vars[0].Value;
}
// calculate all "free" numbers
var numbers = algebraicexpression.Where(x => x.IsVar == false).OrderBy(x => x.locationInEqution).ToList();
int lastResult = 0;
int Result = 0;
if (numbers.Count() > 1)
{
lastResult = GetCalculation(vars[0].Value, vars[1].Value, vars[1].OperatorBefore);
for (int i = 2; i < vars.Count(); i++)
{
Result = GetCalculation(lastResult, vars[i].Value, vars[i].OperatorBefore);
lastResult = varResult;
}
}
else if (numbers.Count() == 1)
{
Result = numbers[0].Value;
}
string stringresult = string.Empty;
if (varResult != 0)
{
stringresult = varResult.ToString() + vars[0].Notation;
}
if (Result > 0)
{
stringresult = stringresult + "+" + Result.ToString();
}
else if (Result < 0)
{
stringresult = stringresult + "-" + Result.ToString();
}
return stringresult;
}
private static int GetCalculation(int x, int y, string eqoperator)
{
if (eqoperator == "+")
{
return x + y;
}
else if (eqoperator == "-")
{
return x - y;
}
else if (eqoperator == "*")
{
return x * y;
}
else if (eqoperator == "/")
{
return x / y;
}
else
{
return 0;
}
}
}
class Part
{
public string MyAlgebricPart;
public string OperatorBefore;
public string OperatorAfter;
public int locationInEqution;
public Part(string part, string operatorbefore, string operatorafter, int location)
{
this.MyAlgebricPart = part;
this.OperatorAfter = operatorafter;
this.OperatorBefore = operatorbefore;
this.locationInEqution = location;
}
public int Value
{
get
{
if (MyAlgebricPart.Count() == 1 && Notation != string.Empty)
{
return 1;
}
else
{
string result = new String(MyAlgebricPart.Where(Char.IsDigit).ToArray());
return Convert.ToInt32(result);
}
}
}
public string Notation
{
get
{
var onlyLetters = new String(MyAlgebricPart.Where(Char.IsLetter).ToArray());
if (onlyLetters != "")
{
return onlyLetters[0].ToString();
}
else
{
return string.Empty;
}
}
}
public bool IsVar
{
get
{
if (Notation == string.Empty)
return false;
else
return true;
}
}
}

Message box for the replaced values count

I have a task called Find and Replace in the DataGridView - It's completed.But i want the replaced count in the message box.
Can anyone help me how to achieve this? Below is my Find and Replace code:
private void btnFindandReplace_Click(object sender, EventArgs e)
{
f.cmbColumnCombo.DataSource = cmbList;
f.ShowDialog();
if (recNo > 0)
recNo = recNo - 30;
LoadPage(MyFOrmat, true);
}
public void LoadPage(string Format, bool isFindAndReplace = false)
{
int startRec;
int endRec;
if (currentPage == PageCount)
{
endRec = (int)maxRec;
}
else
{
endRec = (int)pageSize * currentPage;
}
dataGridView1.Rows.Clear();
if (recNo == 0)
{
dataGridView1.Columns.Clear();
}
int rowindex = 0;
startRec = recNo;
for (int RowCount = startRec; RowCount <= endRec; RowCount++)
{
if (datfile[RowCount].ToString() != "" )
{
if (RowCount == 0)
{
string[] column = datfile[RowCount].Split('þ');
for (int i = 0; i < column.Length - 1; i++)
{
if (column[i].ToString() != "") //if (column[i].ToString() != "" && column[i].ToString() != "\u0014")
{
DataGridViewTextBoxColumn dgvtxtcountry = new DataGridViewTextBoxColumn();
dgvtxtcountry.HeaderText = column[i].ToString();
dgvtxtcountry.Name = column[i].ToString();
dataGridView1.Columns.Add(dgvtxtcountry);
cmbList.Add(column[i]);
// dataGridView1.Columns["Sent Date"].DefaultCellStyle.Format = "dd/MM/yyyy";
i += 1;
}
}
}
if (RowCount != 0)
{
dataGridView1.Rows.Add();
string[] column = datfile[RowCount].Split('þ');
int index = 0;
for (int i = 1; i < column.Length - 1; i++)
{
if (column[i].ToString() != "\u0014")
{
//if (i == 3)
//{
// dataGridView1.Rows[rowindex].Cells[index].Value = Convert.ToDateTime(column[i]).ToString(Format);
//}
//else
//{
dataGridView1.Rows[rowindex].Cells[index].Value = column[i].Trim('þ');
//}
if (StaticVar.FnR == true && index == StaticVar.colindx)
{
if ((column[i]).Contains(StaticVar.Find) != null)
dataGridView1.Rows[rowindex].Cells[index].Value = column[i].Replace(StaticVar.Find, StaticVar.Replace);
}
if (StaticVar.DateFormat != "" && StaticVar.DateFormat != null)
{
if (StaticVar.datecolidx == ((i - 1) / 2))
{
dataGridView1.Rows[rowindex].Cells[index].Value = Convert.ToDateTime(column[i]).ToString(StaticVar.DateFormat);
}
}
index += 1;
i += 1;
}
}
rowindex += 1;
}
}
recNo += 1;
}
}
Declare the replaced variable and increment it every time you replace a value. Show a message box at the end of the method.
public void LoadPage(string Format, bool isFindAndReplace = false) {
int replaced = 0;
....
if ((column[i]).Contains(StaticVar.Find) != null) {
dataGridView1.Rows[rowindex].Cells[index].Value = column[i].Replace(StaticVar.Find, StaticVar.Replace);
replaced++;
}
....
if(isFindAndReplace)
MessageBox.Show(string.Format("{0} occurrence(s) replaced.", replaced));
}

Performance issue with traversing&&filtering datagridview in c#

Currently, I am doing a log analyzer for my personal project.
My issue here is that I am new to c# and I have an performance issue with my tool.
Everytime the device(iOS) is interacted, I get an output syslog from a library and it comes in to the output handler.
public void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine, iosSyslogger form, string uuid)
{
string currentPath = System.Environment.CurrentDirectory;
bool exit = false;
if (exit == true) return;
try
{
form.BeginInvoke(new Action(() =>
{
form.insertLogText = outLine.Data;
}));
using (System.IO.StreamWriter file = new System.IO.StreamWriter(currentPath + #"\syslog" + uuid + ".txt", true))
{
file.WriteLine(outLine.Data);
}
}
catch
{
return ;
}
//*Most of the logic for outputing the log should be dealt from this output Handler
}
Then, I write the outline.Data to Data grid view. My concern is that I need to be able to search and filter through data gridview.
Curently I am using visibility = false for search filtering ( if the row does not match the given filter specification I set the row to visibility =false)
This requires the program to traverse the entire datagridview to check whether the condition is met.
Will there be any better way to filter and search within ?
(When I have thousands of lines of row, it takes at least 20 seconds to process it)
Below is the code for filtering, and searching through the results function.
private void searchResult(string term)
{
if (term != null)
{
int i = 0;
while (i < dataGridView1.Rows.Count - 1)
{
if (dataGridView1.Rows[i].Cells[3] == null)
{
i++;
continue;
}
if (dataGridView1.Rows[i].Visible == false)
{
i++;
continue;
}
else if (dataGridView1.Rows[i].Cells[2].Value.ToString().Contains(term) || dataGridView1.Rows[i].Cells[3].Value.ToString().Contains(term) || dataGridView1.Rows[i].Cells[4].Value.ToString().Contains(term))
{
string multirow = dataGridView1.Rows[i].Cells[5].Value.ToString();
int count = Convert.ToInt32(multirow);
if (count > 0)
{
int z = 0;
for (z = 0; z <= count; z++)
{
dataGridView1.Rows[i + z].Visible = true;
}
i = i + z;
}
else
{
dataGridView1.Rows[i].Visible = true;
i++;
}
}
else
{
dataGridView1.Rows[i].Visible = false;
i++;
}
}
}
}
public filteringThelist(){
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
dataGridView1.Rows[i].Visible = false;
int count1,count2,count3=0;
count1 = 1;
count2 = 1;
count3 = 1;
int z = 0;
foreach (KeyValuePair<string, string> entry in totalSelected)
{
if (entry.Value == "devicename" && dataGridView1.Rows[i].Cells[1].Value != null)
{
if (dataGridView1.Rows[i].Cells[1].Value.ToString().Trim().Equals(entry.Key.Trim()))
{
string multirow1 = dataGridView1.Rows[i].Cells[5].Value.ToString();
int counts = Convert.ToInt32(multirow1);
if (counts > 0)
{
for (z = 0; z < counts; z++)
{
dataGridView1.Rows[i + z].Visible = true;
}
}
else
{
dataGridView1.Rows[i].Visible = true;
}
}
else if (devicename.CheckedItems.Count > 1&&count1!= devicename.CheckedItems.Count)
{
count1++;
continue;
}
else
{
dataGridView1.Rows[i].Visible = false;
break;
}
}
else if (entry.Value == "process" && dataGridView1.Rows[i].Cells[2].Value != null)
{
if (dataGridView1.Rows[i].Cells[2].Value.ToString().Trim().Equals(entry.Key.Trim()))
{
string multirow1 = dataGridView1.Rows[i].Cells[5].Value.ToString();
int counts = Convert.ToInt32(multirow1);
if (counts > 0)
{
for (z = 0; z < counts; z++)
{
dataGridView1.Rows[i + z].Visible = true;
}
}
else
{
dataGridView1.Rows[i].Visible = true;
}
}
else if (processlistname.CheckedItems.Count > 1 && count2 != processlistname.CheckedItems.Count)
{
count2++;
continue;
}
else
{
dataGridView1.Rows[i].Visible = false;
break;
}
}
else if (entry.Value == "loglevel" && dataGridView1.Rows[i].Cells[3].Value != null)
{
if (dataGridView1.Rows[i].Cells[3].Value.ToString().Trim().Contains(entry.Key.Trim()))
{
string multirow1 = dataGridView1.Rows[i].Cells[5].Value.ToString();
int counts = Convert.ToInt32(multirow1);
if (counts > 0)
{
for (z = 0; z < counts; z++)
{
dataGridView1.Rows[i + z].Visible = true;
}
}
else
{
dataGridView1.Rows[i].Visible = true;
}
continue;
}
else if (loglevelCheckBox.CheckedItems.Count > 1 && count3 != loglevelCheckBox.CheckedItems.Count)
{
count3++;
continue;
}
else
{
dataGridView1.Rows[i].Visible = false;
break;
}
}
// do something with entry.Value or entry.Key
}
string multirow = dataGridView1.Rows[i].Cells[5].Value.ToString();
int count = Convert.ToInt32(multirow);
if (count > 0&& dataGridView1.Rows[i].Visible==false)
{
for (int k = 0; k <= count; k++)
{
dataGridView1.Rows[i + k].Visible = false;
}
}
i = i + z;
}
The performance problem is because your DataGridView is redrawing at each modification.
Don't fill the DataGridView directly from your Data. Rather create a DataTable and bind it to DataGridView with a BindingSource.
Then use the "Filter" property of the binding source to view extracts of dataTable in the DataGridView. The "Filter" property is a string whose content is similar to that of a WHERE SQL clause.

Categories

Resources