3
\$\begingroup\$

I wrote a program in that prints a file through the following steps:

  1. Makes a copy of a base file

    Test Rest
    ----------------------------------
    Test Street N 123
    TaxPayer: 123123123

    Bill [BillType]
    ----------------------------------
    Client [ClientTaxpayer]
    Date: [Date] Hour: [Hour]
    ==================================
    Qnt Product Valor Tax
    ----------------------------------

Code Used:

string Path = AppDomain.CurrentDomain.BaseDirectory + @"\Settings\Printer\Temp.txt";
using (StreamReader _SR = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + @"\Settings\Printer\BaseBill.txt"))
{
    using (StreamWriter _SW = new StreamWriter(Path))
    {
        _SW.Write(_SR.ReadToEnd());
        _SW.Dispose();
    }
}
  1. Start changing files lines and setup some variables

Code Used:

            arrLine = File.ReadAllLines(Path).ToList();

            LineChanger("  Bill Simple", Path, 6);
            LineChanger("  Client " + _TaxPayerTxt.Text, Path, 8);
            #region Date
            string Date = "  " + "Date: " + Year + "-" + Moth + "-" + Day + "        Hour: " + Hours + ":" + Minutes + ":" + Secound;
            #endregion
            LineChanger(Date, Path, 9);
            List<string> LastSteep = new List<string>();
            int i2 = 0;
            for (int i = 0; i < Products.Count; i++)
            {
                //LastSteep.Add("  " + Qnt[i] + "    " + Products[i] + "         " + Value[i]);
                string Start = "  " + Qnt[i];
                int QntS = Qnt[i].Length;
                if (QntS == 1)
                {
                    string space = "";
                    if (Products[i].Length > 12)
                    {
                        Products[i] = Products[i].Remove(12, Products[i].Length - 12);
                        space += " ";
                    }
                    else
                    {
                        for (int i3 = 0; i3 < 13- Products[i].Length; i3++)
                        {
                            space += " ";
                        }
                    }
                    string Start2 = "    " + Products[i] + space + Value[i] + "         " + Tax[i] + "%";
                    LastSteep.Add(Start + Start2);
                }

            }

            foreach (string _Add in LastSteep)
            {
                i2++;
                LineChanger(_Add, Path, 12 + i2);
            }

            LineChanger("  ==================================", Path, 13 + i2);
            LineChanger("  \u001D!\u0011\u001BE\u0001TOTAL   " + Total + "\u001BE\0\u001D!\0", Path, 14 + i2);
            LineChanger("  Payment Type:   " + PayMethod, Path, 15 + i2);
            LineChanger("  ----------------------------------", Path, 16 + i2);
            LineChanger("  Tax              IVA     Incidence", Path, 17 + i2);
            LineChanger("  ----------------------------------", Path, 18 + i2);
            List<string> TaxList = new List<string>();
            for (int i = 0; i < Products.Count; i++)
            {
                string Start = "  " + Tax[i] + "%";
                string TaxL = Tax[i];
                if (TaxL == "23")
                {
                    string Space1 = "              ";
                    Start += Space1;
                    decimal iva = Convert.ToDecimal(Value[i]);
                    decimal Incidente = iva /1.23m;
                    iva =  Incidente * 23 / 100;
                    iva =  Math.Round(iva, 2);
                    Incidente = Math.Round(Incidente, 2);
                    Start += iva;
                    Start += "    " + Incidente;
                    TaxList.Add(Start);
                }
                else if(TaxL == "13")
                {
                    string Space1 = "              ";
                    Start += Space1;
                    decimal iva = Convert.ToDecimal(Value[i]);
                    decimal Incidente = iva / 1.13m;
                    iva = Incidente * 13 / 100;
                    iva = Math.Round(iva, 2);
                    Incidente = Math.Round(Incidente, 2);
                    Start += iva;
                    Start += "    " + Incidente;
                    TaxList.Add(Start);
                }
                else if (TaxL == "6")
                {
                    string Space1 = "               ";
                    Start += Space1;
                    decimal iva = Convert.ToDecimal(Value[i]);
                    decimal Incidente = iva / 1.06m;
                    iva = Incidente * 6 / 100;
                    iva = Math.Round(iva, 2);
                    Incidente = Math.Round(Incidente, 2);
                    Start += iva;
                    Start += "    " + Incidente;
                    TaxList.Add(Start);
                }
            }

            foreach (string _Item in TaxList)
            {
                i2++;
                LineChanger(_Item, Path, 19 + i2);
            }

            LineChanger("  ----------------------------------", Path, 20 + i2);
            LineChanger("  Proccessed by WinTest", Path, 21 + i2);
            LineChanger("  Certificate N 0/AT", Path, 22 + i2);
            LineChanger("  ", Path, 23 + i2);
            LineChanger("  Counter: " + _MenuForm._Menu._LocationLabel.Text + " " + _MenuForm._Menu._LocNumbLab.Text + " Employee: " + _MenuForm._Menu._LogedUser.Text, Path, 24 + i2);
            LineChanger("  ", Path, 25 + i2);
            LineChanger("  ", Path, 26 + i2);
            LineChanger("  ", Path, 27 + i2);

            using (StreamWriter _SR = new StreamWriter(Path))
            {
                foreach (string _Srt in arrLine)
                {
                    _SR.WriteLine(_Srt);
                }
                _SR.Dispose();
            }

            #endregion

Line Changer Function:

    static void LineChanger(string newText, string fileName, int line_to_edit)
    {
        try
        {
            arrLine[line_to_edit - 1] = newText;
        }
        catch
        {
            arrLine.Add(newText);
        }
    }
  1. Then it prints everything

Code Used:

string Comm2 = "SELECT * FROM Settings WHERE Name='Printer'";
IEnumerable<Settings> _Printer;
using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
{
    Con.Open();
    _Printer = Con.Query<Settings>(Comm2);
    Con.Close();
}

foreach (Settings _Selected in _Printer)
{
    PrintDocument _PrintDoc = new PrintDocument();
    _PrintDoc.PrinterSettings.PrinterName = _Selected.Value;
    Printer.SendFileToPrinter(_PrintDoc.PrinterSettings.PrinterName, AppDomain.CurrentDomain.BaseDirectory + @"\Settings\Printer\Temp.txt");
    string ESC = Convert.ToString((char)27);
    string GS = Convert.ToString((char)29);
    string COMMAND = "";
    COMMAND = ESC + "@";
    COMMAND += GS + "V" + (char)1;
    Printer.SendStringToPrinter(_PrintDoc.PrinterSettings.PrinterName, COMMAND);

}
File.Delete(Path);

Printer Class:

public class Printer
{
    // Structure and API declarions:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class DOCINFOA
    {
        [MarshalAs(UnmanagedType.LPStr)]
        public string pDocName;
        [MarshalAs(UnmanagedType.LPStr)]
        public string pOutputFile;
        [MarshalAs(UnmanagedType.LPStr)]
        public string pDataType;
    }
    [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

    [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool ClosePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool StartDocPrinter(IntPtr hPrinter, int level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

    [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool EndDocPrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool StartPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool EndPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, out int dwWritten);

    // SendBytesToPrinter()
    // When the function is given a printer name and an unmanaged array
    // of bytes, the function sends those bytes to the print queue.
    // Returns true on success, false on failure.
    public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, int dwCount)
    {
        int dwError = 0, dwWritten = 0;
        IntPtr hPrinter = new IntPtr(0);
        DOCINFOA di = new DOCINFOA();
        bool bSuccess = false; // Assume failure unless you specifically succeed.

        di.pDocName = "My C#.NET RAW Document";
        di.pDataType = "RAW";

        // Open the printer.
        if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
        {
            // Start a document.
            if (StartDocPrinter(hPrinter, 1, di))
            {
                // Start a page.
                if (StartPagePrinter(hPrinter))
                {
                    // Write your bytes.
                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                    EndPagePrinter(hPrinter);
                }
                EndDocPrinter(hPrinter);
            }
            ClosePrinter(hPrinter);
        }
        // If you did not succeed, GetLastError may give more information
        // about why not.
        if (bSuccess == false)
        {
            dwError = Marshal.GetLastWin32Error();
        }
        return bSuccess;
    }

    public static bool SendFileToPrinter(string szPrinterName, string szFileName)
    {
        // Open the file.
        FileStream fs = new FileStream(szFileName, FileMode.Open);
        // Create a BinaryReader on the file.
        BinaryReader br = new BinaryReader(fs);
        // Dim an array of bytes big enough to hold the file's contents.
        byte[] bytes = new byte[fs.Length];
        bool bSuccess = false;
        // Your unmanaged pointer.
        IntPtr pUnmanagedBytes = new IntPtr(0);
        int nLength;

        nLength = Convert.ToInt32(fs.Length);
        // Read the contents of the file into the array.
        bytes = br.ReadBytes(nLength);
        // Allocate some unmanaged memory for those bytes.
        pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
        // Copy the managed byte array into the unmanaged array.
        Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
        // Send the unmanaged bytes to the printer.
        bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
        // Free the unmanaged memory that you allocated earlier.
        Marshal.FreeCoTaskMem(pUnmanagedBytes);
        fs.Dispose();
        return bSuccess;
    }
    public static bool SendStringToPrinter(string szPrinterName, string szString)
    {
        IntPtr pBytes;
        int dwCount;
        // How many characters are in the string?
        dwCount = szString.Length;
        // Assume that the printer is expecting ANSI text, and then convert
        // the string to ANSI text.
        pBytes = Marshal.StringToCoTaskMemAnsi(szString);
        // Send the converted ANSI string to the printer.
        SendBytesToPrinter(szPrinterName, pBytes, dwCount);
        Marshal.FreeCoTaskMem(pBytes);
        return true;
    }
}

It takes around 6 seconds to finish all the steps. I am looking for advice to increase the performance.

All Code:

using Dapper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinTest
{
    public partial class _PayFrom : Form
    {
        string Total;

    string PayMethod;
    public static _PayFrom _PF;

    static List<string> arrLine;
    public _PayFrom(string _PayMethod, string _Total)
    {
        InitializeComponent();
        Total = _Total;
        PayMethod = _PayMethod;
        _PF = this;
    }

    private void _SaveBtn_Click(object sender, EventArgs e)
    {
        #region CheackNIF
        bool NIFISOK = CheackNIF(_TaxPayerTxt.Text);
        if (!NIFISOK)
        {
            MessageBox.Show("Invalid NIF");
            return;
        }
        #endregion

        #region CheackIfClientExists
        string SqlCom = "SELECT * FROM Clients WHERE Taxpayer='" + _TaxPayerTxt.Text + "'";

        IEnumerable<Clients> SelectedClient;

        using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
        {
            Con.Open();
            SelectedClient = Con.Query<Clients>(SqlCom);
            Con.Close();
        }

        if (SelectedClient.Count() == 0)
        {
            string Comm = "INSERT INTO Clients (Name, Taxpayer) VALUES('" + _NameTxt.Text + "', '" + _TaxPayerTxt.Text + "')";

            using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
            {
                Con.Open();
                Con.Query(Comm);
                Con.Close();
            }

            using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
            {
                Con.Open();
                SelectedClient = Con.Query<Clients>(SqlCom);
                Con.Close();
            }
        }

        foreach (Clients Selected in SelectedClient)
        {
            #region SetDate
            DateTime Now = DateTime.Now;
            int Year = Now.Year;
            int Moth = Now.Month;
            int Day = Now.Day;
            int Hours = Now.Hour;
            int Minutes = Now.Minute;
            int Secound = Now.Second;
            string CurrTime = Year + "-" + Moth + "-" + Day + " " + Hours + ":" + Minutes + ":" + Secound;
            #endregion

            #region GetProducts

            List<string> Products = new List<string>();
            List<string> Qnt = new List<string>();
            List<string> Value = new List<string>();
            List<string> Tax = new List<string>();

            string AllProducts = "";

            int count = 0;

            for (int i = 0; i < _MenuForm._Menu._ProductsGrid.Rows.Count; i++)
            {
                Products.Add(_MenuForm._Menu._ProductsGrid.Rows[i].Cells[1].Value.ToString());
                Qnt.Add(_MenuForm._Menu._ProductsGrid.Rows[i].Cells[0].Value.ToString());
                Value.Add(_MenuForm._Menu._ProductsGrid.Rows[i].Cells[2].Value.ToString());
                Tax.Add(_MenuForm._Menu._ProductsGrid.Rows[i].Cells[3].Value.ToString());
            }

            foreach (string Product in Products)
            {
                if (count == 0)
                {
                    AllProducts = Product;
                    count++;
                }
                else
                {
                    AllProducts += ", " + Product;
                }
            }
            #endregion

            #region Correct Total

            Total = Total.Replace(",", ".");

            #endregion

            string Comm = "INSERT INTO Sales (ClientID, Total, [Date], Products, PaymentMethod) VALUES('" + Selected.id +
                              "', '" + Total + "', '" + CurrTime + "', '" + AllProducts +
                              "', '" + PayMethod + "')";

            using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
            {
                Con.Open();
                Con.Query(Comm);
                Con.Close();
            }
            #region PrepereEverything for printing
            string Path = AppDomain.CurrentDomain.BaseDirectory + @"\Settings\Printer\Temp.txt";
            using (StreamReader _SR = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + @"\Settings\Printer\BaseBill.txt"))
            {
                using (StreamWriter _SW = new StreamWriter(Path))
                {
                    _SW.Write(_SR.ReadToEnd());
                    _SW.Dispose();
                }
            }

            arrLine = File.ReadAllLines(Path).ToList();

            LineChanger("  Bill Simple", Path, 6);
            LineChanger("  Client " + _TaxPayerTxt.Text, Path, 8);
            #region Date
            string Date = "  " + "Date: " + Year + "-" + Moth + "-" + Day + "        Hour: " + Hours + ":" + Minutes + ":" + Secound;
            #endregion
            LineChanger(Date, Path, 9);
            List<string> LastSteep = new List<string>();
            int i2 = 0;
            for (int i = 0; i < Products.Count; i++)
            {
                //LastSteep.Add("  " + Qnt[i] + "    " + Products[i] + "         " + Value[i]);
                string Start = "  " + Qnt[i];
                int QntS = Qnt[i].Length;
                if (QntS == 1)
                {
                    string space = "";
                    if (Products[i].Length > 12)
                    {
                        Products[i] = Products[i].Remove(12, Products[i].Length - 12);
                        space += " ";
                    }
                    else
                    {
                        for (int i3 = 0; i3 < 13- Products[i].Length; i3++)
                        {
                            space += " ";
                        }
                    }
                    string Start2 = "    " + Products[i] + space + Value[i] + "         " + Tax[i] + "%";
                    LastSteep.Add(Start + Start2);
                }

            }

            foreach (string _Add in LastSteep)
            {
                i2++;
                LineChanger(_Add, Path, 12 + i2);
            }

            LineChanger("  ==================================", Path, 13 + i2);
            LineChanger("  \u001D!\u0011\u001BE\u0001TOTAL   " + Total + "\u001BE\0\u001D!\0", Path, 14 + i2);
            LineChanger("  Payment Type:   " + PayMethod, Path, 15 + i2);
            LineChanger("  ----------------------------------", Path, 16 + i2);
            LineChanger("  Tax              IVA     Incidence", Path, 17 + i2);
            LineChanger("  ----------------------------------", Path, 18 + i2);
            List<string> TaxList = new List<string>();
            for (int i = 0; i < Products.Count; i++)
            {
                string Start = "  " + Tax[i] + "%";
                string TaxL = Tax[i];
                if (TaxL == "23")
                {
                    string Space1 = "              ";
                    Start += Space1;
                    decimal iva = Convert.ToDecimal(Value[i]);
                    decimal Incidente = iva /1.23m;
                    iva =  Incidente * 23 / 100;
                    iva =  Math.Round(iva, 2);
                    Incidente = Math.Round(Incidente, 2);
                    Start += iva;
                    Start += "    " + Incidente;
                    TaxList.Add(Start);
                }
                else if(TaxL == "13")
                {
                    string Space1 = "              ";
                    Start += Space1;
                    decimal iva = Convert.ToDecimal(Value[i]);
                    decimal Incidente = iva / 1.13m;
                    iva = Incidente * 13 / 100;
                    iva = Math.Round(iva, 2);
                    Incidente = Math.Round(Incidente, 2);
                    Start += iva;
                    Start += "    " + Incidente;
                    TaxList.Add(Start);
                }
                else if (TaxL == "6")
                {
                    string Space1 = "               ";
                    Start += Space1;
                    decimal iva = Convert.ToDecimal(Value[i]);
                    decimal Incidente = iva / 1.06m;
                    iva = Incidente * 6 / 100;
                    iva = Math.Round(iva, 2);
                    Incidente = Math.Round(Incidente, 2);
                    Start += iva;
                    Start += "    " + Incidente;
                    TaxList.Add(Start);
                }
            }

            foreach (string _Item in TaxList)
            {
                i2++;
                LineChanger(_Item, Path, 19 + i2);
            }

            LineChanger("  ----------------------------------", Path, 20 + i2);
            LineChanger("  Proccessed by WinTest", Path, 21 + i2);
            LineChanger("  Certificate N 0/AT", Path, 22 + i2);
            LineChanger("  ", Path, 23 + i2);
            LineChanger("  Counter: " + _MenuForm._Menu._LocationLabel.Text + " " + _MenuForm._Menu._LocNumbLab.Text + " Employee: " + _MenuForm._Menu._LogedUser.Text, Path, 24 + i2);
            LineChanger("  ", Path, 25 + i2);
            LineChanger("  ", Path, 26 + i2);
            LineChanger("  ", Path, 27 + i2);

            using (StreamWriter _SR = new StreamWriter(Path))
            {
                foreach (string _Srt in arrLine)
                {
                    _SR.WriteLine(_Srt);
                }
                _SR.Dispose();
            }

            #endregion

            #region Print

            string Comm2 = "SELECT * FROM Settings WHERE Name='Printer'";
            IEnumerable<Settings> _Printer;
            using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
            {
                Con.Open();
                _Printer = Con.Query<Settings>(Comm2);
                Con.Close();
            }

            foreach (Settings _Selected in _Printer)
            {
                PrintDocument _PrintDoc = new PrintDocument();
                _PrintDoc.PrinterSettings.PrinterName = _Selected.Value;
                Printer.SendFileToPrinter(_PrintDoc.PrinterSettings.PrinterName, AppDomain.CurrentDomain.BaseDirectory + @"\Settings\Printer\Temp.txt");
                string ESC = Convert.ToString((char)27);
                string GS = Convert.ToString((char)29);
                string COMMAND = "";
                COMMAND = ESC + "@";
                COMMAND += GS + "V" + (char)1;
                Printer.SendStringToPrinter(_PrintDoc.PrinterSettings.PrinterName, COMMAND);

            }
            File.Delete(Path);

            #endregion
            _MenuForm._Menu._TotalTxt.Text = "0";
            _MenuForm._Menu.RemoveProducts();
            Payment_Methods._Pay_Met.ThisClose();
            Close();
        }
        #endregion
    }

    public bool CheackNIF(string NIF)
    {
        string s;
        string contrib;
        char c;
        int checkDigit;
        contrib = NIF;
        s = contrib;
        if (s.Length == 9)
        {
            c = s[0];
            //Digitos iniciais válidos
            if (c == '1' || c == '2' || c == '3' || c == '5' || c == '6' || c == '8' || c == '9')
            {
                checkDigit = (c - '0') * 9;

                for (int i = 2; i <= 8; i++)
                    checkDigit += (s[i - 1] - '0') * (10 - i);

                checkDigit = 11 - (checkDigit % 11);

                if (checkDigit >= 10)
                    checkDigit = 0;

                if (checkDigit == (s[8] - '0'))
                    return true;
            }
        }

        return false;
    }

    private void _FConsumer_Click(object sender, EventArgs e)
    {
        #region SetDate
        DateTime Now = DateTime.Now;
        int Year = Now.Year;
        int Moth = Now.Month;
        int Day = Now.Day;
        int Hours = Now.Hour;
        int Minutes = Now.Minute;
        int Secound = Now.Second;
        string CurrTime = Year + "-" + Moth + "-" + Day + " " + Hours + ":" + Minutes + ":" + Secound;
        #endregion

        #region GetProducts

        List<string> Products = new List<string>();

        string AllProducts = "";

        int count = 0;

        for (int i = 0; i < _MenuForm._Menu._ProductsGrid.Rows.Count; i++)
        {
            Products.Add(_MenuForm._Menu._ProductsGrid.Rows[i].Cells[1].Value.ToString());
        }

        foreach (string Product in Products)
        {
            if (count == 0)
            {
                AllProducts = Product;
                count++;
            }
            else
            {
                AllProducts += ", " + Product;
            }
        }
        #endregion

        #region Correct Total

        Total = Total.Replace(",", ".");

        #endregion

        string Comm = "INSERT INTO Sales (ClientID, Total, [Date], Products, PaymentMethod) VALUES('" + null +
                          "', '" + Total + "', '" + CurrTime + "', '" + AllProducts +
                          "', '" + PayMethod + "')";

        using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
        {
            Con.Open();
            Con.Query(Comm);
            Con.Close();
        }
        Payment_Methods._Pay_Met.ThisClose();
        Close();
    }

    private void _ClientListBtn_Click(object sender, EventArgs e)
    {
        _ClientList _CL = new _ClientList();
        _CL.ShowDialog();
    }

    private void _PayFrom_Load(object sender, EventArgs e)
    {

    }

    static void LineChanger(string newText, string fileName, int line_to_edit)
    {
        try
        {
            arrLine[line_to_edit - 1] = newText;
        }
        catch
        {
            arrLine.Add(newText);
        }
    }
}
}

`

Update

After debugging i found out that the part of the code that toke more time (about 2-3 seconds) is this

    LineChanger("  ==================================", Path, 13 + i2);
    LineChanger("  \u001D!\u0011\u001BE\u0001TOTAL   " + Total + "\u001BE\0\u001D!\0", Path, 14 + i2);
    LineChanger("  Payment Type:   " + PayMethod, Path, 15 + i2);
    LineChanger("  ----------------------------------", Path, 16 + i2);
    LineChanger("  Tax              IVA     Incidence", Path, 17 + i2);
    LineChanger("  ----------------------------------", Path, 18 + i2);
    LineChanger("  ----------------------------------", Path, 20 + i2);
    LineChanger("  Proccessed by WinTest", Path, 21 + i2);
    LineChanger("  Certificate N 0/AT", Path, 22 + i2);
    LineChanger("  ", Path, 23 + i2);
    LineChanger("  Counter: " + _MenuForm._Menu._LocationLabel.Text + " " + _MenuForm._Menu._LocNumbLab.Text + " Employee: " + _MenuForm._Menu._LogedUser.Text, Path, 24 + i2);
    LineChanger("  ", Path, 25 + i2);
    LineChanger("  ", Path, 26 + i2);
    LineChanger("  ", Path, 27 + i2);
\$\endgroup\$
13
  • 1
    \$\begingroup\$ Is there are reason you're not using File.Copy to copy the file? Since you're not doing any progress visualization or anything it should be optimized. About the other code I would use a profiler to see what exactly is slow and can be optimized. That is a good start in a program like this I guess. Edit: It looks like you read the file ofter with File.ReadAllLines, that should be cached if you call it often, depending on the size of the file it can be pretty slow to read it again and again. \$\endgroup\$
    – xander
    Commented Aug 8, 2017 at 11:05
  • 1
    \$\begingroup\$ The LineChanger method is probably one of the more expensive ones. Each time you call it, you read the contents completely, make your change and save it again. I can imagine that this would be one of the more expensive parts of your program. And personally, I don't see any reason for having the GC calls that are waiting for stuff, can you comment on why you believe you needed to add these? \$\endgroup\$
    – Icepickle
    Commented Aug 8, 2017 at 11:09
  • \$\begingroup\$ The code you've shown here is not complete. Would you mind updating it so it compiles properly? \$\endgroup\$ Commented Aug 8, 2017 at 11:24
  • \$\begingroup\$ @xander the reason i don't use File.Copy is because if i use it it will not allow to delete the file later \$\endgroup\$
    – Bot Wade
    Commented Aug 8, 2017 at 11:27
  • \$\begingroup\$ @Icepickle GC was a code i forget to delete \$\endgroup\$
    – Bot Wade
    Commented Aug 8, 2017 at 11:31

3 Answers 3

4
\$\begingroup\$

First thing I see

using (StreamWriter _SW = new StreamWriter(Path))
{
    _SW.Write(_SR.ReadToEnd());
    _SW.Dispose();
}

when you use a using statement on something, it automatically disposes the item that it is using, that is one of the reasons to use a using statement, Just get rid of the Dispose

using (StreamWriter _SW = new StreamWriter(Path))
{
    _SW.Write(_SR.ReadToEnd());
}

Same thing here

        using (StreamWriter _SR = new StreamWriter(Path))
        {
            foreach (string _Srt in arrLine)
            {
                _SR.WriteLine(_Srt);
            }
            _SR.Dispose();
        }

you don't need the _SR.Dispose();


I also found some redundancy in one of your for loops

        for (int i = 0; i < Products.Count; i++)
        {
            string Start = "  " + Tax[i] + "%";
            string TaxL = Tax[i];
            if (TaxL == "23")
            {
                string Space1 = "              ";
                Start += Space1;
                decimal iva = Convert.ToDecimal(Value[i]);
                decimal Incidente = iva /1.23m;
                iva =  Incidente * 23 / 100;
                iva =  Math.Round(iva, 2);
                Incidente = Math.Round(Incidente, 2);
                Start += iva;
                Start += "    " + Incidente;
                TaxList.Add(Start);
            }
            else if(TaxL == "13")
            {
                string Space1 = "              ";
                Start += Space1;
                decimal iva = Convert.ToDecimal(Value[i]);
                decimal Incidente = iva / 1.13m;
                iva = Incidente * 13 / 100;
                iva = Math.Round(iva, 2);
                Incidente = Math.Round(Incidente, 2);
                Start += iva;
                Start += "    " + Incidente;
                TaxList.Add(Start);
            }
            else if (TaxL == "6")
            {
                string Space1 = "               ";
                Start += Space1;
                decimal iva = Convert.ToDecimal(Value[i]);
                decimal Incidente = iva / 1.06m;
                iva = Incidente * 6 / 100;
                iva = Math.Round(iva, 2);
                Incidente = Math.Round(Incidente, 2);
                Start += iva;
                Start += "    " + Incidente;
                TaxList.Add(Start);
            }
        }

there is some code that can be pulled out and put before the for loop and some that can be put after the if statements, inside the for loop. like this

for (int i = 0; i < Products.Count; i++)
{
    string Start = "  " + Tax[i] + "%              ";
    string TaxL = Tax[i];
    decimal iva = Convert.ToDecimal(Value[i]);
    if (TaxL == "23")
    {
        decimal Incidente = iva /1.23m;
        iva =  Incidente * 23 / 100;
    }
    else if(TaxL == "13")
    {
        decimal Incidente = iva / 1.13m;
        iva = Incidente * 13 / 100;
    }
    else if (TaxL == "6")
    {
        decimal Incidente = iva / 1.06m;
        iva = Incidente * 6 / 100;
    }
    iva =  Math.Round(iva, 2);
    Incidente = Math.Round(Incidente, 2);
    Start += iva + "    " + Incidente;
    TaxList.Add(Start); 
}

we are already concatenating, so I just merged some of that together so there are less lines and less assigning to variables inside of the for loop


Same thing as Earlier with the SQL Connections, when using one, you don't have to close it inside of a using statement. but that isn't really the issue here:

   using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
   {
       Con.Open();
       SelectedClient = Con.Query<Clients>(SqlCom);
       Con.Close();
   }

   if (SelectedClient.Count() == 0)
   {
       string Comm = "INSERT INTO Clients (Name, Taxpayer) VALUES('" + _NameTxt.Text + "', '" + _TaxPayerTxt.Text + "')";

       using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
       {
           Con.Open();
           Con.Query(Comm);
           Con.Close();
       }

       using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
       {
           Con.Open();
           SelectedClient = Con.Query<Clients>(SqlCom);
           Con.Close();
       }
   }

you should only open the connection once, do everything you need to do and then close the Connection to the SQL Server

Like this:

using (SqlConnection Con = new SqlConnection("data source=VBSS012;initial catalog=WinTest_Beta;integrated security=True"))
{
    Con.Open();
    SelectedClient = Con.Query<Clients>(SqlCom);
    if (SelectedClient.Count() == 0)
    {
        string Comm = "INSERT INTO Clients (Name, Taxpayer) VALUES('" + _NameTxt.Text + "', '" + _TaxPayerTxt.Text + "')";
        Con.Query(Comm);
        SelectedClient = Con.Query<Clients>(SqlCom);
    }
}

you also do this more than once, so I took a closer look at this, and I don't think you are doing what you want to do most efficiently, this is obfuscated at best. I should be able to look at your code and know what it is doing.

    foreach (string Product in Products)
    {
        if (count == 0)
        {
            AllProducts = Product;
            count++;
        }
        else
        {
            AllProducts += ", " + Product;
        }
    }

this would be cleaner as a for loop instead of a foreach loop

something like this:

for (int 1 = 0; i < Products.Length - 1; i++)
{
    if (i = 0)
    {
        AllProducts = Products[i];
    }           
    AllProducts += ", " + Products[i];
}

but then this got me to thinking that maybe you should be doing something like this instead.

string allProducts = string.Join(", ",Products);

what this does is put all your products into a comma separated list for you, way simpler than the for loop, and it is built in (.NET4+)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ now it takes lees then a second thank you for you collaboration \$\endgroup\$
    – Bot Wade
    Commented Aug 8, 2017 at 12:52
2
\$\begingroup\$

Focusing only on LineChanger()

Why is this method and the arrLine static ? I don't see any reason why this shouldn't be a class variable and method.

Instead of using try..catch you should check the Count of the List<string> if you can update the item at the specific index or if you add to the List<>.

What is the string fileName method parameter doing here ? It is never used so it should be removed.

LineChanger isn't a good name either because it isn't descriptive enough. It doesn't only change a line of text but eventually add some string to the list. Maybe AddOrUpdate or something like this would be better.

Method arguments should be named using camelCase casing hence line_to_edit -> lineToEdit

Keeping the name and the static just to show you how I would do it so you can easily adopt to your code

static void LineChanger(string newText, int lineToEdit)
{
    if (arrLine.Count >= lineToEdit)
    {
        arrLine[lineToEdit - 1] = newText;
    }
    else
    {
        arrLine.Add(newText);
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ now it takes lees then a second thank you for you collaboration \$\endgroup\$
    – Bot Wade
    Commented Aug 8, 2017 at 12:52
2
\$\begingroup\$

Here are a few quick pointers for you.

Function length: Some of your functions, especially _SaveBtn_Click, are massive. Splitting a lot of this code out into smaller clearly named functions will make reuse and modification much easier and faster.

Classes: You use a lot of primatives: int, string etc. Consider wrapping them in classes to make their usage clearer.

Magic numbers:

if(TaxL == "23")... 

? What is special about 23?

int meaningful_name = 23;
if(TaxL == meaningful_name) ... 

This is much clearer, but actually still terrible. Now I have no idea what TaxL means. You are not limited to four characters. Longer variable names are much clearer.

\$\endgroup\$
2
  • \$\begingroup\$ 23 is important because it is the IVA of food and Products were in Portugal \$\endgroup\$
    – Bot Wade
    Commented Aug 8, 2017 at 15:43
  • \$\begingroup\$ Ok - so a variable name like food_and_products_IVA would be a good choice. This will help make the code easier to read in the future. \$\endgroup\$
    – David
    Commented Aug 9, 2017 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.