Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно писать программу, Особенности С# 
:(
    Опции темы
WantToProg
Дата 1.12.2009, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 13.4.2009

Репутация: нет
Всего: нет



Дело в том, что моя тема не просит ответить на вопрос, как сделать, чтоб работало. Все как ни странно работает. 
Основная проблема, это то, что я не знаю как правильно подойти к написанию программы. Где что определить, как к чему обращаться.
Я прошу взглянуть на код написаный мной (не без помощи васsmile) И указать на ошибки, посоветовать как правильно писать, чтобы в дальнейшем использовать полученные советы, в написании других программ
Итак, код:
Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Net.NetworkInformation;

namespace MyTestProgramm
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }
        
        private void StartSrvtoolStripButton1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(Server);
            t.Start();            
            tabControl1.Visible = true;
            tabPage1.Focus();
            richTextBox1.Text = "Server started!!!";
        }

        static void Server()
        {
            String Filename, con, price, sendName, name;
            String num, BarCode, strmsgname, strmsgprice, dtr, strmsg;
            
            int i, dac;
            
            Filename = "D:\\NewFolder\\index.txt";
            StreamReader sr = new StreamReader(Filename, System.Text.Encoding.Default);
            List<string> data = new List<string>();
            while ((con = sr.ReadLine()) != null)
            {
                string[] split = con.Split(';');
                num = split[0];
                data.Add(num);
                BarCode = split[1];
                data.Add(BarCode);
                name = split[2];
                data.Add(name);
                sendName = split[3];
                data.Add(sendName);
                price = split[4];
                data.Add(price);
            }

            TcpListener listener = new TcpListener(IPAddress.Any, 9001);
            metka:
            listener.Start();
            byte [] bytes = new byte[1];
            using (TcpClient c = listener.AcceptTcpClient())
            using (NetworkStream n = c.GetStream())

                while (true)
                    
                {
                    Ping pingSender = new Ping();
                    PingOptions options = new PingOptions();
                    options.DontFragment = true;
                    string datasend = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
                    byte[] buffer = Encoding.ASCII.GetBytes(datasend);
                    int timeout = 120;
                    PingReply reply = pingSender.Send("192.168.5.221", timeout, buffer, options);
                    
                    if (reply.Status != IPStatus.Success)
                    { 
                        listener.Stop();
                        goto metka;
                    }
                List<string> dataArray = new List<string>();
                dataArray.Clear();
                while (n.DataAvailable)
                {
                    n.Read(bytes, 0, 1);
                    dtr = Encoding.ASCII.GetString(bytes, 0, 1);
                    if (dtr != "F")
                    {
                        if (dtr != "\r")
                        {
                            if (dtr != "E")
                            {
                                dataArray.Add(dtr);
                                continue;
                            }
                        }

                    }
                    else continue;
                    dac = dataArray.Count();
                    strmsg = null;
                    for (int y = 0; y < dac; y++)
                    {
                        strmsg = strmsg + dataArray[y];
                    }
                    for (i = 0; i < data.Count(); i++)
                        if (data[i] == strmsg)
                        {
                            int k = i + 2;
                            strmsgname = data[k];
                            string left25 = strmsgname.Substring(0, 16);
                            string mid25 = strmsgname.Substring(16);
                            strmsgprice = data[k + 1];
                            byte[] snl = System.Text.Encoding.Default.GetBytes(left25);
                            byte[] snm = System.Text.Encoding.Default.GetBytes(mid25);
                            byte[] sp = System.Text.Encoding.Default.GetBytes(strmsgprice);
                            byte[] ClearScreen = new byte[] {27, 37};
                            byte[] NewString = new byte[] { 27, 10 };
                            byte[] FitScreen = new byte[] {27, 44};
                            byte[] RightBottom = new byte[] { 27, 46, 56 };
                            byte[] crlf = new byte[] { 13, 10 };
                            BinaryWriter w = new BinaryWriter(n);
                            n.Write(ClearScreen, 0, 2);
                            n.Write(snl, 0, snl.Length); 
                            n.Write(crlf, 0, 2);         
                            n.Write(snm, 0, snm.Length);
                            n.Write(RightBottom, 0, 3);                            
                            n.Write(sp, 0, sp.Length);
                            w.Write(0x03);
                            n.Flush();                  
                            break;
                        }
                }        
            }
            
        listener.Stop();
            
        } 
        
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
 
            Application.Exit();

        }        
    }
}        




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

PS: Прошу прощения если разместил не там где нужно. Перенесите если не сложно в "Общие вопросы по .NET и C#"

Это сообщение отредактировал(а) WantToProg - 1.12.2009, 14:01
PM MAIL   Вверх
LamerTM
Дата 2.12.2009, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



Если тебя интересует оформление кода, то это сюда:

"Соглашения по оформлению кода команды RSDN"
http://www.rsdn.ru/article/mag/200401/codestyle.XML
PM MAIL   Вверх
Экскалупатор
Дата 2.12.2009, 13:31 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



WantToProg, такое ощущение, что это просто структурный код помещенный в оболочку формы и запускающийся по нажатию кнопки, да и даже для структурного он как то жестковат. 
 static void Server(), я бы лично разделил штук на пять отдельных методов, а лучше в отдельном статическом классе реализовал. отдельные строки для меня вообще остаются загадкой:

Код

byte [] bytes = new byte[1];


зачем делать массив размером 1? если dtr это строка, и у тебя всегда один байт, может можно как то проще это сделать?

Код

goto metka;


это вообще не айс. делает код еще больше запутанным. мало того что у тебя трех этажные циклы вложенные в друг друга, так еще и это.

да и вообще просмотри хорошо свой код. например: для чего такое условие цикла?
Код

while (true)


Добавлено через 4 минуты и 6 секунд
в общем в ответ на твой вопрос "как правильно писать программу" - это надо так сделать что бы человек(не комп, ему все равно, он поймет в любом случае, он же ее выполняет) мог прочитать твою программу и понять что в ней происходит.
PM MAIL ICQ   Вверх
WantToProg
Дата 2.12.2009, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 13.4.2009

Репутация: нет
Всего: нет



Цитата(LamerTM @  2.12.2009,  12:39 Найти цитируемый пост)
Если тебя интересует оформление кода, то это сюда:

"Соглашения по оформлению кода команды RSDN"
http://www.rsdn.ru/article/mag/200401/codestyle.XML 

Оно конечно хорошо, но немного не это меня интересовало. В основном проблема касается понятности кода

Цитата(Экскалупатор @  2.12.2009,  13:31 Найти цитируемый пост)
это вообще не айс. делает код еще больше запутанным. мало того что у тебя трех этажные циклы вложенные в друг друга, так еще и это.

Вот от этого хотелось бы избавится, понять как правильно делать

Цитата(Экскалупатор @  2.12.2009,  13:31 Найти цитируемый пост)
static void Server(), я бы лично разделил штук на пять отдельных методов, а лучше в отдельном статическом классе реализовал

Вот тут самая проблема, что не ясно как это сделать.
Я уже не первую программу пишу и основная моя проблема, не могу найти ошибку, в том, что написал.
Если не сложно, покажите как оно делается правильно, на примере этой программы.

PS: Краткое описание программы:
Запускаем TCP сервер и ждем подключения. Когда клиент подключается, запускаем цикл проверки входящих сообщений, плюс пингуем, на наличие клиента в сети. Если клиент отпал(сети нет, кабель перегрызли), то переходим в режим прослушивания, и ждем подключения следующего клиента.
В принципе все просто и работает. Но программа написана исключительно криво, а как написать ее правильно, я не знаю :(
PM MAIL   Вверх
Экскалупатор
Дата 2.12.2009, 15:17 (ссылка) |    (голосов:6) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



по организации кода можно почитать:
Макконел "Совершенный код"
Мартин Фаулер "Рефакторинг"
PM MAIL ICQ   Вверх
sergioK
Дата 15.1.2010, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 15.2.2008

Репутация: нет
Всего: нет



[QUOTE=WantToProg,2.12.2009,  14:50][QUOTE=LamerTM, Но программа написана исключительно криво, а как написать ее правильно, я не знаю :([/QUOTE]
Когда то лет 10 назад один человек мне сказал - размер отдельной взятой функции не должен превышать размер экрана в котором она пишеться ,
начни с этого , ну и про goTo забудь,  а вобще то этим вещам годами учаться 
PM MAIL   Вверх
tol05
Дата 15.1.2010, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



Цитата(Экскалупатор @  2.12.2009,  14:17 Найти цитируемый пост)
по организации кода можно почитать:
Макконел "Совершенный код"
Мартин Фаулер "Рефакторинг" 

поддерживаю


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
kobra
Дата 16.1.2010, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Цитата(sergioK @  15.1.2010,  15:27 Найти цитируемый пост)
Когда то лет 10 назад один человек мне сказал - размер отдельной взятой функции не должен превышать размер экрана в котором она пишеться 
согласен. но к сажалению не всегда получается. 
Цитата(sergioK @  15.1.2010,  15:27 Найти цитируемый пост)
а вобще то этим вещам годами учаться 
вот тут есть две пути.
1. пишем так, как в вышеописанном коде, потом выносим в отделние модули то, что нужно вынести.
2. сначало продумываем все методы, пишем, а потом в основном методе их визываем.

goto не самый лущи вариант выити из цикла, тем более что после этого опять заходит в тотже цикл. да и while (true) я бы заменил на рекурсию.



PM MAIL   Вверх
WolfTheGrey
Дата 16.1.2010, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 21.1.2009
Где: forum.vingrad.ru

Репутация: нет
Всего: 2



1-старайся обьявлять переменные в начале класса.
2- нравится goto metka; - пользуйся. Тока в твоем коде я думаю что она слишком ранно стоит.
при каждом переходе на метку вновь и вновь будет вызываться "listener.Start();" - зачем, ты же сервер?

я бы метод пинга реализовал в новом потоке (чтоб не отвлекал). И смысл пинговать, когда при разъединении TCP вызывается на сервере ошибка  Exeption, обработай его: закрой соедиение, удали пользователя...

Добавлено через 12 минут и 51 секунду
При UDP соединении можно пинговаьть, так как ни клиент о сервере и сервер о клиенте ни чего не знают.
PM MAIL   Вверх
CasperSC
Дата 19.1.2010, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 203
Регистрация: 27.11.2009

Репутация: нет
Всего: 1



Почитал тут и подумал: "Интересная темка"! Меня тоже этот вопрос интересует. Пишу программу и паралельно учу язык, так в ходе написания, я узнаю например, что для хранения настроек программы не обязательно использовать промежуточную структуру, хотя местами без этого ну ни как, например для отмены внесённых изменений в форме настроек, на забинденых контролах.
Есть такой код и почему-то мне кажется тоже кривой до безобразия, щелчок по pictureBox играющему роль анимированой кнопки:
Суть: при нажатии на кнопке или иконке в трее, если в настройка выбрано "Использовать анимированные показ и скрытие главного окна", то форма "уезжает" за панель задач. Иначе просто скрывается.
Код

private void pictureBox2_Click(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.UseAnimationHide)
            {
                this.AnimatedHide(); //в следующем примере, что ниже описыватся происходящее
            }
            else
            {
                this.Hide();
            }       
        }


Код

        /// <summary>
        /// Анимировано прячет форму
        /// </summary>
        private void AnimatedHide()
        {
            Point pLoc = new Point(this.Location.X, this.Location.Y);
            if (this.Location.Y < Screen.PrimaryScreen.Bounds.Height)
            {
                while (this.Location.Y < Screen.PrimaryScreen.Bounds.Height)
                {
                    pLoc.Y += 40;
                    this.Location = pLoc;
                    System.Threading.Thread.Sleep(10);
                }
                
            }
            this.Hide();
        }


щелчок по значку в трее:

Код

private void trayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.Visible)
            {
                if (Properties.Settings.Default.UseAnimationHide)
                {
                    this.AnimatedHide();
                }
                else
                {
                    this.Hide();
                }
            }
            else
            {
                if (Properties.Settings.Default.UseAnimationHide)
                {
                    this.AnimatedShow();
                }
                else
                {
                    //так как используется смена положения Y 
                    //в анимированном скрытии, то при выключении этой возможности
                    //форма могла остаться за экраном
                    this.Location = poinLocation; //в poinLocation храниться первоначальное положение формы при старте программы (центр экрана)
                    this.Show();
                }
            }
        }


Код

        /// <summary>
        /// Анимированно востанавливает форму (показывает)
        /// </summary>
        private void AnimatedShow()
        {
            Point pLoc = new Point(this.Location.X, this.Location.Y);
            int yScreen = ((Screen.PrimaryScreen.Bounds.Height / 2) / 2) + 50; //почему-то без +50 форма вылазиет выше (Border окна?)
            if (this.Location.Y > yScreen)
            {
                this.Show();
                while (this.Location.Y > yScreen)
                {
                    pLoc.Y -= 40;
                    this.Location = pLoc;
                    System.Threading.Thread.Sleep(10);
                }
            }
            else
            {
                this.Location = poinLocation;
                this.Show();
            }
            this.Refresh();
        }


Прокоментируйте пожалуйста свои мысли. Мне кажется прячу и востанавливаю форму криво, что кривее некуда, может есть способ лучше? Особенно  System.Threading.Thread.Sleep(10); и вообще весь цикл. Помоиму этот  System.Threading.Thread.Sleep(10); тормозит всю программу.
PM MAIL   Вверх
Экскалупатор
Дата 19.1.2010, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



Код

if (this.Location.Y < Screen.PrimaryScreen.Bounds.Height)
            {
                while (this.Location.Y < Screen.PrimaryScreen.Bounds.Height)


зачем два раза проверять одно и тоже? иф не нужен совсем.
PM MAIL ICQ   Вверх
CasperSC
Дата 19.1.2010, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 203
Регистрация: 27.11.2009

Репутация: нет
Всего: 1



Цитата(Экскалупатор @ 19.1.2010,  17:48)
Код

if (this.Location.Y < Screen.PrimaryScreen.Bounds.Height)
            {
                while (this.Location.Y < Screen.PrimaryScreen.Bounds.Height)


зачем два раза проверять одно и тоже? иф не нужен совсем.

Хм... даже не замечал этого. А то что криво написано я имел ввиду сам цикл и всё, что в нём. Может и не криво, просто других способов не видел. Через таймер было бы без  System.Threading.Thread.Sleep(10); но не удобно.
PM MAIL   Вверх
Экскалупатор
Дата 19.1.2010, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



CasperSC, мне кажется лучше сделать один метод для скрытия(т.е. один для скрытия и один для раскрытия) формы. и что бы уже в методе решалось как именно прятать/открывать форму. т.е. что бы не в обработчике выбирался вариант скрытия, а именно сам метод решал. это уменьшило бы количество ифоф.

Это сообщение отредактировал(а) Экскалупатор - 20.1.2010, 11:29
PM MAIL ICQ   Вверх
Exception
Дата 20.1.2010, 04:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 29
Всего: 186



Цитата(Экскалупатор @  2.12.2009,  16:17 Найти цитируемый пост)
по организации кода можно почитать:
Макконел "Совершенный код"
Мартин Фаулер "Рефакторинг" 


ДА!
PM   Вверх
WolfTheGrey
Дата 21.1.2010, 14:44 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 21.1.2009
Где: forum.vingrad.ru

Репутация: нет
Всего: 2



System.Threading.Thread.Sleep(10)

замени его на: System.Windows.Threading.DispatcharTimer

он по лучше с формой себя ведет. Thread.sleep() он поток замораживает (форму) а DispatcharTimer  тайминг отсчитывает.

И почему не хочеш воспользоваться классами там всякими: AnimationDuration

Добавлено через 1 минуту и 37 секунд
А вобще мне понравился твой код, не заграмажденный.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0862 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.