Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Отваливается прога


Автор: Ripperr 19.12.2009, 03:29
Отваливается прога без ответа и привета... в журнале ощибок оставляет метку

Код

Тип события:    Ошибка
Источник события:    .NET Runtime
Категория события:    Отсутствует
Код события:    1026
Дата:        18.12.2009
Время:        18:38:09
Пользователь:        Н/Д
Компьютер:    ***
Описание:
Application: PhoneBilling-server.exe
Framework Version: v4.0.21006
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException
Stack:
   at System.Data.Odbc.OdbcDataReader.GetValue(Int32)
   at System.Data.Odbc.OdbcDataReader.get_Item(Int32)
   at WindowsFormsApplication3.Form1.line_analystic(System.Object)
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart(System.Object)




ругается я так понял на функцию line_analystic

прога компилится под Visual Studio 2010 и NET 4.0 прога отваливается произвольно пробовал гонять данные имитируще процесс работы вроде все стабильно но в реальной ситуаци отлитает в течении дня ....

Ругать не строго с шарпом и студей токо начал разбератся прогу эту написал изучая язык а точнее с первого по 7 днень общения основной период времени пытался приручить прогу к мускулу и разобратся чего оно отваливается по пункту 2 безуспешно...

вот собственно функция

Код

        public void line_analystic(object data) //Обработка строк
        {
            string ext, trk, call_date, call_time, duration, number, ext_name, ext_groupe, incoming_line;
            incoming_line = ""+data+"";
            Match row_m = Regex.Match(incoming_line, @" (?<ext>\d{3,3})\s+(?<trk>\d{3,3})\s+(?<call_date>\d{1,2}:\d{1,2})\s+(?<call_time>\d{1,2}:\d{1,2}:\d{1,2})\s+(?<duration>\d{1,2}:\d{1,2}:\d{1,2})\s+(?<number>[0-9x]+)");
            if (row_m.Success)
            {
                if (OdbcCon.State == ConnectionState.Closed)
                {
                    OdbcCon.Open();
                }
                ext = row_m.Groups["ext"].Value;                                        //внутрений
                trk = row_m.Groups["trk"].Value;                                        //горотская линия
                string trk_name;
                string[] temp = row_m.Groups["call_date"].Value.Split(':');
                call_date = temp[1] + "/" + temp[0] + "/" + DateTime.Now.Year;          //дата звонка
                call_time = row_m.Groups["call_time"].Value;                            //время звонка
                duration = row_m.Groups["duration"].Value;                              //продолжительность
                number = row_m.Groups["number"].Value.Trim('x');                        //номер набора

                    //Установка подключения К БД
                    //Было здесь подключение к БД
                    //Получение Абонента и группы из его внутренего номера
                    OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT Owner,Groupes  FROM phones WHERE InPhone =  '" + ext + "'", OdbcCon);
                    OdbcDR = OdbcCom.ExecuteReader();
                    OdbcDR.Read();
                    ext_name   = "" + OdbcDR[0] + "";
                    ext_groupe = "" + OdbcDR[1] + "";
                    //Номер городской линии
                    OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT nomera.Tel FROM nomera WHERE nomera.Line =  '" + trk + "'", OdbcCon);
                    OdbcDR = OdbcCom.ExecuteReader();
                    OdbcDR.Read();
                    trk_name = Convert.ToString(OdbcDR[0]);

                    //Получение инфорации о направлении звонка
                    String country_in_digit = number.Substring(0, 1); //Код выхода на межгород
                    String country_in_code = number.Substring(0, 3);  //Код города в Стране
                    if (country_in_digit != "0" || country_in_code == maskedTextBox7.Text)
                    {
                        //Получение названия Зоны и Тарифа
                        OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT zones.Zone_Name, zones.Tarif_1_1 FROM zones WHERE zones.No_Zone ='1'", OdbcCon);
                        OdbcDR = OdbcCom.ExecuteReader();
                        OdbcDR.Read();
                        string zone_name  = Convert.ToString(OdbcDR[0]);
                        double zone_price = Convert.ToDouble(OdbcDR[1]);
                        double curr_rate  = Convert.ToDouble(maskedTextBox8.Text);
                        //Цена звонка
                        double call_price = callprice(duration, zone_price, curr_rate);
                        //Добавление данных в базу данных
                        OdbcCom = new System.Data.Odbc.OdbcCommand("INSERT INTO Statist VALUES (NULL,'" + datetime_encoding(call_date, call_time) + "', '" + ext_name + "', '" + duration + "','" + zone_name + "','" + zone_name + "','" + number + "','" + price_encoding(call_price) + "','" + ext_groupe + "','" + trk_name + "','" + ext + "') ", OdbcCon);
                        OdbcDR = OdbcCom.ExecuteReader();
                    }
                    String country_out_digit = number.Substring(0, 2); //Код выхода на международные звонки
                    if (country_in_digit == "0" && country_out_digit != "00")
                    {
                        //Страна
                        //Получение Названия города и зоны
                        OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT sng.country, sng.No_Zone FROM sng WHERE sng.code = '" + number.Substring(0, 3) + "'", OdbcCon);
                        OdbcDR = OdbcCom.ExecuteReader();
                        OdbcDR.Read();
                        string city_name = Convert.ToString(OdbcDR[0]);
                        string city_zone = Convert.ToString(OdbcDR[1]);
                        //Получение названия Зоны и Тарифа
                        OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT zones.Zone_Name, zones.Tarif_1_1 FROM zones WHERE zones.No_Zone ='" + city_zone + "'", OdbcCon);
                        OdbcDR = OdbcCom.ExecuteReader();
                        OdbcDR.Read();
                        string zone_name = Convert.ToString(OdbcDR[0]);
                        double zone_price = Convert.ToDouble(OdbcDR[1]);
                        double curr_rate = Convert.ToDouble(maskedTextBox8.Text);
                        //Цена звонка
                        double call_price = callprice(duration, zone_price, curr_rate);
                        //Добавление данных в базу данных
                        OdbcCom = new System.Data.Odbc.OdbcCommand("INSERT INTO Statist VALUES (NULL,'" + datetime_encoding(call_date, call_time) + "', '" + ext_name + "', '" + duration + "','" + zone_name + "','" + city_name + "','" + number + "','" + price_encoding(call_price) + "','" + ext_groupe + "','" + trk_name + "','" + ext + "') ", OdbcCon);
                        OdbcDR = OdbcCom.ExecuteReader();
                    }
                    if (country_out_digit == "00")
                    {
                        //Мир получение страны и зоны
                        OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT inter.country, inter.No_Zone FROM inter WHERE inter.code = '" + number.Substring(2, 1) + "'", OdbcCon);
                        OdbcDR = OdbcCom.ExecuteReader();
                        OdbcDR.Read();
                        if (OdbcDR[0] == null)
                        {
                            OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT inter.country, inter.No_Zone FROM inter WHERE inter.code = '" + number.Substring(2, 2) + "'", OdbcCon);
                            OdbcDR = OdbcCom.ExecuteReader();
                            OdbcDR.Read();
                            if (OdbcDR[0] == null)
                            {
                                OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT inter.country, inter.No_Zone FROM inter WHERE inter.code = '" + number.Substring(2, 3) + "'", OdbcCon);
                                OdbcDR = OdbcCom.ExecuteReader();
                                OdbcDR.Read();
                                string country_name = Convert.ToString(OdbcDR[0]);
                                string country_zone = Convert.ToString(OdbcDR[1]);
                                //Получение названия Зоны и Тарифа
                                OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT zones.Zone_Name, zones.Tarif_1_1 FROM zones WHERE zones.No_Zone ='" + country_zone + "'", OdbcCon);
                                OdbcDR = OdbcCom.ExecuteReader();
                                OdbcDR.Read();
                                string zone_name = Convert.ToString(OdbcDR[0]);
                                double zone_price = Convert.ToDouble(OdbcDR[1]);
                                double curr_rate = Convert.ToDouble(maskedTextBox8.Text);
                                //Цена звонка
                                double call_price = callprice(duration, zone_price, curr_rate);

                                //Добавление данных в базу данных
                                OdbcCom = new System.Data.Odbc.OdbcCommand("INSERT INTO Statist VALUES (NULL,'" + datetime_encoding(call_date, call_time) + "', '" + ext_name + "', '" + duration + "','" + zone_name + "','" + country_name + "','" + number + "','" + price_encoding(call_price) + "','" + ext_groupe + "','" + trk_name + "','" + ext + "') ", OdbcCon);
                                OdbcDR = OdbcCom.ExecuteReader();
                            }
                            else
                            {
                                string country_name = Convert.ToString(OdbcDR[0]);
                                string country_zone = Convert.ToString(OdbcDR[1]);
                                //Получение названия Зоны и Тарифа
                                OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT zones.Zone_Name, zones.Tarif_1_1 FROM zones WHERE zones.No_Zone ='" + country_zone + "'", OdbcCon);
                                OdbcDR = OdbcCom.ExecuteReader();
                                OdbcDR.Read();
                                string zone_name = Convert.ToString(OdbcDR[0]);
                                double zone_price = Convert.ToDouble(OdbcDR[1]);
                                double curr_rate = Convert.ToDouble(maskedTextBox8.Text);
                                //Цена звонка
                                double call_price = callprice(duration, zone_price, curr_rate);
                                //Добавление данных в базу данных
                                OdbcCom = new System.Data.Odbc.OdbcCommand("INSERT INTO Statist VALUES (NULL,'" + datetime_encoding(call_date, call_time) + "', '" + ext_name + "', '" + duration + "','" + zone_name + "','" + country_name + "','" + number + "','" + price_encoding(call_price) + "','" + ext_groupe + "','" + trk_name + "','" + ext + "') ", OdbcCon);
                                OdbcDR = OdbcCom.ExecuteReader();
                            }
                        }
                        else
                        {
                            string country_name = Convert.ToString(OdbcDR[0]);
                            string country_zone = Convert.ToString(OdbcDR[1]);
                            //Получение названия Зоны и Тарифа
                            OdbcCom = new System.Data.Odbc.OdbcCommand("SELECT zones.Zone_Name, zones.Tarif_1_1 FROM zones WHERE zones.No_Zone ='" + country_zone + "'", OdbcCon);
                            OdbcDR = OdbcCom.ExecuteReader();
                            OdbcDR.Read();
                            string zone_name = Convert.ToString(OdbcDR[0]);
                            double zone_price = Convert.ToDouble(OdbcDR[1]);
                            double curr_rate = Convert.ToDouble(maskedTextBox8.Text);
                            //Цена звонка
                            double call_price = callprice(duration, zone_price, curr_rate);
                            //Добавление данных в базу данных
                            OdbcCom = new System.Data.Odbc.OdbcCommand("INSERT INTO Statist VALUES (NULL,'" + datetime_encoding(call_date, call_time) + "', '" + ext_name + "', '" + duration + "','" + zone_name + "','" + country_name + "','" + number + "','" + price_encoding(call_price) + "','" + ext_groupe + "','" + trk_name + "','" + ext + "') ", OdbcCon);
                            OdbcDR = OdbcCom.ExecuteReader();
                        }

                    }
                    //!Получение инфорации о направлении звонка
                    // Было OdbcCon.Close();            
                }          
        }


вызывается с двух мест (первый при обработке логов)

Код

private void button6_Click(object sender, EventArgs e)    
        {
            string str;
            //Получение полного объема файла
            progressBar2.Value = 0;
            StreamReader sr = new StreamReader(@textBox2.Text);
            progressBar2.Maximum =(int)(sr.BaseStream.Length);//общий размер потока
            ConStr = "DRIVER={MySQL ODBC 5.1 Driver};SERVER=" + maskedTextBox1.Text + ";PORT=3306;UID=" + maskedTextBox2.Text + ";PWD=" + maskedTextBox3.Text + ";DATABASE=" + comboBox3.Text + ";OPTION=3";
            OdbcCon = new System.Data.Odbc.OdbcConnection(ConStr);
            if (OdbcCon.State == ConnectionState.Closed)
            {
                OdbcCon.Open();
            }
            while ((str = sr.ReadLine()) != null)
            {
                if (str != "")
                {
                    Thread analystic = new Thread(line_analystic);
                    analystic.Start(str);
                    analystic.Join();
                    //line_analystic(str); 
                }
                progressBar2.Value = (int)(sr.BaseStream.Position);
            }
            
            sr.Close();
        }



а так-же чтении данных с ком порта в раельных условиях работает имменнов  этом режим при надобности выложу сурсы и пример даных прикреплен.

Код

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string row;
            row = (serialPort1.ReadLine());
            //Проверка подключения к БД
            if (OdbcCon.State == ConnectionState.Closed)
            {
                OdbcCon.Open();
            }
            //!Проверка подключения к БД
            if(row != "") 
            {

                Thread analystic = new Thread(line_analystic);
                analystic.Start(row);
                analystic.Join();
            }
            if (checkBox2.Checked == true)
            {
                textBox6.Text = textBox3.Text + DateTime.Now.ToString("dd.MM.yyyy") + ".log";
                log_write(row, textBox6.Text);
            }
            else
            {
                textBox6.Text = "Ведение логов отключено !!!";
            }
            richTextBox1.AppendText(row + "\n\r");
        }


помоги кто чем может ибо только начал разбератся а тут такой кирпич перед носом ....
пытался раскидать по тредам (неселен в этом) но нечего это не дало (немного прибавило скорости). Попутный вопрос как сделать так чтобы треды виртуально были автономными ибо иногда при вополнении скюэль запросов появляются какието неверные данные поэтому пришлось поставить дожидатся завершения выполнения потока. 
правилам крсивого кодо-писания некто не учил поэтому написал в меру своих познаний если кто наставит на путь истеный буду благодарен.

Автор: ДобренькийПапаша 19.12.2009, 08:46
Возможно там где вы читаете из odbcDR, например 28-я строка в первом коде.

надо написать:
Код

while(odbcDR.Read()
{
     //Здесь обращаться уже к объекту SqlDataReader.
}


Мне кажется, что когда вы обращаетесь к odbcDR[1] вы и получаете ошибку.

Автор: Ripperr 19.12.2009, 15:08
Запрос возврашает 1 строку с 2мя перемеными мне кажется тут цикл не надо... я цикл пользовал когда строк приходит n но я попробую ваш вариант

как сделать так чтобы переменные было видно на протяжении всей функции ... потомучто если я добавляю цикл while переменные полученные в нем недоступны коду идущему под ним

Автор: ДобренькийПапаша 19.12.2009, 16:59
После того как сделали odbcDR.Read(), сделайте odbcDr.Close();

Вообще возьмите за привычку закрывать потоки. Или оборачивайте в using, когда объект создаёте. 

Автор: Ripperr 19.12.2009, 17:20
Поподробнее обо оборачивать в using я ж написал "7 день" общения с шарпой

Автор: wester 19.12.2009, 17:53
Ripperr, 
msdn есть....

http://msdn.microsoft.com/ru-ru/library/yh598w02.aspx

Автор: Ripperr 19.12.2009, 18:08
а что он дает ? using

Автор: ДобренькийПапаша 19.12.2009, 18:23
Ты попробовал закрыть поток и обращаться в цикле? Если не помогло, тогда не знаю. Нужен твой солюшен, но у тебя база там, поэтому не знаю как мне самому отдебажить...

Автор: Ripperr 19.12.2009, 19:01
в цикле не пробовал но там непонятки с перемеными если перемены врашаются в цикле то к ним пото в не цикла нельзя обрашатся

и как обойти 

"Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on."

Автор: Ripperr 19.12.2009, 19:50
я вот одного понять не могу я создал виртулально комп порт закидываю туда данные порядка 5000 строк программа не вылетела а там внезапно закрывается .... правда у меня win7 ... а  там XP

Автор: Ripperr 22.12.2009, 18:39
После моих манипуляций с закрытием потока появилась вот така ощибка (через день работы проги)

Код

Тип события:    Ошибка
Источник события:    .NET Runtime
Категория события:    Отсутствует
Код события:    1026
Дата:        22.12.2009
Время:        8:13:37
Пользователь:        Н/Д
Компьютер:    
Описание:
Application: PhoneBilling-server.exe
Framework Version: v4.0.21006
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException
Stack:
   at System.Data.Odbc.OdbcConnection.ConnectionIsAlive(System.Exception)
   at System.Data.Odbc.OdbcConnection.HandleErrorNoThrow(System.Data.Odbc.OdbcHandle, RetCode)
   at System.Data.Odbc.OdbcConnection.HandleError(System.Data.Odbc.OdbcHandle, RetCode)
   at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(System.Data.CommandBehavior, System.String, Boolean, System.Object[], SQL_API)
   at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(System.Data.CommandBehavior, System.String, Boolean)
   at System.Data.Odbc.OdbcCommand.ExecuteReader(System.Data.CommandBehavior)
   at System.Data.Odbc.OdbcCommand.ExecuteReader()
   at WindowsFormsApplication3.Form1.line_analystic(System.Object)
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart(System.Object)



Автор: tol05 22.12.2009, 19:02
Цитата(Ripperr @  19.12.2009,  02:29 Найти цитируемый пост)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32)
   at System.Data.Odbc.OdbcDataReader.get_Item(Int32)
   at WindowsFormsApplication3.Form1.line_analystic(System.Object)


по всему видать, что не может reader по целочисленному индексу вернуть ничего.
в
Цитата(Ripperr @  19.12.2009,  02:29 Найти цитируемый пост)
 public void line_analystic(object data) //Обработка строк

везде где идет обращение к индексатору а -ля "OdbcDR[0]" "OdbcDR[1]"
нужно проверять, а есть ли у readera елемент с индексом 0, с индексом 1 и т.п. Что он вообще прочитал?

Автор: Ripperr 22.12.2009, 19:27
Это как обясни плз поподробнее ...  smile 

Автор: ДобренькийПапаша 22.12.2009, 19:46
Можно проверить что возвращает ваш запрос например так (если я пользуюсь SQL Server 2005):
Вывести через MessageBox.Show() (непосредственно перед вызовом хранимки) все параметры передаваемые в хранимую процедуру на сервере. После этого беру пишу тот же запрос, что и в хранимке, подставляя вместо параметров значения выведенные в MessageBox. После этого глядим что сервер вернул. Собственно после этого, обычно, становится очевидно, в чём проблема...

Может это можно как то и быстрее сделать... Я лично делаю так и доволен.

p.s.
А то, что не возвращет reader элемент под номером 1 означает скорее всего то, что его просто нет... То есть запрос работает некорректно. Скорее всего сам запрос то не заваливается нигде, просто он составлен некорректно для решения вашей задачи.

Автор: Ripperr 22.12.2009, 20:01
у меня mySQL  у меня в качестве БД ... поводу проверки а можно както сделать если запрос возврашает пустоту то просто прерывать выполнение функция

Автор: Ripperr 22.12.2009, 20:57
фокус в том что прога может работать по 10 часов ... и не отваливаться а может внезапно закрыться в самом начале прога стабильно работает на 2х моих машинах на win7 и win2008 что на одной что на второй у меня не получилось завалить приложение ..... пробовал всю ночь грузить поток на комп порт (виртуально так как устройства самомго нету у меня он стоит только на серверной машыне) но поток идентичен тому что грузит устройство так как я пишу лог при получении строк этот лог  я гружу в ком ... так вот за 2 ночи по не отвалилось ... на хр сп3 я видел что прога отлетала в самом начале как только открывалась а бывает работает по 2 дня ... непонятно почему такой разнабой ... просто было бы неплоха чтобы она писала последний стак перемных когда она отвалисась чтобы хоть чтото понять можно было....

Автор: ДобренькийПапаша 22.12.2009, 22:14
Как вариант можете отдельно логировать значения переменных передаваемых в хранимку, от которых, гипотетически, всё и рушится при обращении к ридеру.

Проверить возвращает ли что-то SqlDataReader можно с помощью свойства SqlDataReader.HasRows, которое возвращает true, если объект содержит одну или несколько строк и false, если не содержит.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)