Assalomu alaykum, yordam.uz saytimizga xush kelibsiz.
Bu saytda o`zingizni qiziqtirgan savollarga javob olishingiz va o`z sohangiz bo`yicha savollarga javob berishingiz mumkin. Bizning Oilamizga a'zo bo`lganingiz uchun chuqur Minnatdorchilik bildiramiz !!!

Bir nechta oqimlar bilan ishlash

+3 ovoz
761 marta ko‘rilgan
so‘radi 10 dekabr, 17 SARVARBEK (355 bal)
n ta mijozga ega bo'lgan, sutkasiga 24 soat, haftasiga 7 kun to'xtamasdan avtomatik ravishda ishlab turadigan dastur tuzish kerak. Bu dasturning asosiy vazifasi mijozlardan doimiy ravishda ma'lumotlarni qabul qilib, ularni qayta ishlab turishdan iborat. Dastur Windows Server OSida ishlay oladigan bo'lishi kerak.

Qo'shimcha ma'lumotlar:

1) 3<n<100

2) Mijoz - doimiy ravishda serverga ma'lumotlar jo'natib turuvchi qo'shimcha dastur

Savol: qaysi dasturlash tilidan foydalangan ma'qul, ya'ni ko'p oqimlar bilan ishlashga va doimiy ravishda ishlab turishga mo'ljallangan dasturlash tillari qaysilar?

Javob uchun oldindan rahmat !
izoh qoldirdi 10 dekabr, 17 Saidolim (3,566 bal)
Savolni biroz tushunmadim. oddiy web server bilan sizni etgan narsani qilib bo`lmidimi? yoki dasturingiz uzoq vaqt ishlashga mo`ljallanganmi? agar qiyin ishlari ko`p bo`lsa, men NodeJs (js) yoki VertX (java|js|kotlin) ni tanlagan bo`lar edim.
izoh qoldirdi 11 dekabr, 17 SARVARBEK (355 bal)
tahrirlandi 12 dekabr, 17 SARVARBEK
Dastur ko'p (bir necha oy) vaqt to'xtamasdan ishlashi kere. Hozir dastur C# da socketlar va threadlar yordamida yasalgan. Lekin mijozlar soni ortishi bilan dastur qotishni boshlayapdi.
Mijoz - deganda serverga ma'lumotlar (har 8 sekundda 512 bayt axborot)ni jo'natib turuvchi yordamchi dastur nazarda tutilyapdi. Unda (ma'lumotni jo'natishda) muammo yo'q.
Muammo faqat jo'natilgan axborotlarni qabul qilib olishda bo'lyapdi, ya'ni dastur qotyapdi.

1 ta javob

0 ovoz
javob berdi 12 dekabr, 17 m.kholmirzaev (164 bal)
tanlangan 08 sentabr, 18 SARVARBEK
 
Eng yaxshi javob
Dasturingiz hozir qancha vaqtda malumotlarni obrabotka qilayapti? Bor yo'g'i 512 baytga qotishi demak dasturni arxitekturasida qandaydir notogri yechim qollanilganidan darak beryapti. Kodini tashlasangiz balkim yechimini toparmiz. Menda ham shunga oxshash dastur bor edi. Kelgan ma'lumotlarni pdfga aylantirib bazada saqlardi. Avvaliga oddiy threadlardan foydalanganim uchun bir vaqtda 100-150 ta so'rov kelsa qotib qolardi.  Sababi har safar yana oqim tayyorlash uchun tizim vaqt sarflaydi va shuni oqibatida ham kop xotira talab qilardi ham sust ishlardi. Bu muammoni yechish uchun Thread Pooldan foydalandim. MSDNda alohida aynan shu haqida ma'lumotlar kop.
izoh qoldirdi 15 dekabr, 17 SARVARBEK (355 bal)
MSDN dan thread ni o'rniga Task bibliotekasidan foydalangan yaxshi degan javobni topgandim. O'sha bo'yicha progni qilyotgandim. Lekin sizni izohizdan keyin  ThreadPool haqida o'qib ko'rdim. U haqida ham huddi Task haqidagi gaplarni yozishibdi. Ikkalasini farqi haqida aniq ma'lumotlarni uchratmadim.

"Я согласен с тем, что Tasks - это более эффективный способ использования нескольких процессоров, особенно для расширенных сценариев, но для простых ситуаций ThreadPool.QueueUserWorkItem кажется вполне адекватным." - deb yozishibdi. Sizni fikriz qanaqa, qaysi biridan foydalangan yaxshiroq bo'ladi?


Kod:

private void ForThread()
        {
            packentlength = 0;
            while (true)
            {
                if (form1.CheckForInternetConnection())
                {
                    try
                    {
                        if (Station.seedlinkreader.isConnected())
                        {                     
                                isconnectionfailedthreadint = 0;
                                Station.IsWorking = true;
                                int total_byte_size = 512;
                                byte[] totalbytes = new byte[total_byte_size];
                                Station.seedlinkreader.in1.read(totalbytes, 0, total_byte_size);
                                Packet512 fullpacket = new Packet512(totalbytes);
                                SaveDatFile(fullpacket);
                                currentime = Convert_Btime_To_Datetime(fullpacket.header.record_start_time);
                                textforlastpackettime = "Last Packet time (UTC):" + fullpacket.RecordStartTime();
                                textforpacketlength = "Received Packet count:" + packentlength.ToString();
                                if (isfullchartarea)
                                {
                                    isfullchartarea = false;
                                    textforirsrpackettime = "First Packet time (UTC):" + fullpacket.RecordStartTime();
                                    starttime = Convert_Btime_To_Datetime(fullpacket.header.record_start_time);
                                    isconnectionfailedthread = new Thread(ForIsConnectionFailedThread);
                                    isconnectionfailedthread.Start();
                                    packentlength = 0;
                                }
                                data = fullpacket.datacount;
                                packentlength++;
                                if (!MyGlobalClass.IsEarthQuake)
                                {
                                    int count = 0;
                                    if (Station.IsEarthQuake(fullpacket, ref count))
                                    {
                                        MyGlobalClass.IsEarthQuake = true;
                                        MyGlobalClass.CutStarttime = Convert_Btime_To_Datetime(fullpacket.header.record_start_time).AddMinutes(-1);
                                        MyGlobalClass.CutEndtime = Convert_Btime_To_Datetime(fullpacket.header.record_start_time).AddSeconds(30);
                                        textfortextboxinform1 = Station.stationname + ":" + "Amplituda=" + Station.amplituda + ", Count=" + count + ", IsEarthQuake=true, CutStartTime=" + MyGlobalClass.CutStarttime.ToLongTimeString() + ", CutEndTime=" + MyGlobalClass.CutEndtime.ToLongTimeString();
                                    }
                                }
                                else
                                {
                                    if (currentime.CompareTo(MyGlobalClass.CutEndtime) > 0)
                                    {
                                        form1.Cut(MyGlobalClass.CutStarttime, MyGlobalClass.CutEndtime);
                                        MyGlobalClass.IsEarthQuake = false;
                                    }
                                }
                                points = GetPoints(data, 50);
                                this.Invoke((MethodInvoker)delegate { UpdateCpuChart(); UpdateTime(); UpdateStation(); });                            
                        }
                        else
                        {
                                Station.IsWorking = false;
                                this.Invoke((MethodInvoker)delegate { FailedConnection(); });
                                this.Invoke((MethodInvoker)delegate { UpdateCpuChart(); UpdateTime(); UpdateStation(); });                            
                        }
                    }                    
                    }
                }
                else
                {
                    textfortoolstriplabel1inform1 = "Can't connection in internet, pleese close the software and try again";
                    Station.IsWorking = false;
                    this.Invoke((MethodInvoker)delegate { UpdateStation(); });
                    StopStation();
                    break;
                }
                Thread.Sleep(500);
            }
        }


Yuqoridagi kod bitta mijozga tegishli bo'lgan oqim ishga tushganda bajariladigan funksiya. Dasturda mijozlar soniga qarab bunaqa oqimlar ko'payib boradi
izoh qoldirdi 18 dekabr, 17 m.kholmirzaev (164 bal)
Thread bn Taskni farqi. Thread bu oqim. Task esa vazifa. Threadni bir ish kuchi deyish mumkin. Task esa o'sha ish kuchi orqali bajariladigan vazifa. Yana bilmadim o'zbekchada qanday tushuntirishni. Mana bu link orqali bir o'qib ko'ring. http://qaru.site/questions/25739/what-is-the-difference-between-task-and-thread
Kodingizni sal tushunmadim.
1. Mijoz bilan har doim bog'langan bo'lishi kerakmi?
2. Agar tarmoq uzilsa unda nima qilishi kerak?
3. Statiosn.seedlinkreader.IsConnected nima ish qiladi? Ya'ni nimani ulanganini tekshiradi?
4. Yangi potoklar qanday ishga tushiriladi?

To'liq kartina hosil bo'lishi uchun nima yozgansiz shuni tashlang. Balkim threadlarsiz ham qilish mumkindir.
izoh qoldirdi 19 dekabr, 17 SARVARBEK (355 bal)
1) Mijoz bilan aloqa doimiy ta'minlangan va ulangan bo'lishi shart

2) Agarda qanaqadir muammoga ko'ra (mijozda internet ishlamay qolishi yoki mijozda chiroq o'chishi va h.k.) aloqa uzilsa qayta aloqa tiklangunga qadar dastur shu mijozni 'eshitib' turishi va aloqa tiklanganda avtomatik qayta ulanishi zarur.

3) Station - bu o'zim yaratgan class. Bunda Seismik stansiya,ya'ni mijoz nazarda tutilyapdi. Bu class barcha classlardan yuqorida turuvchi class hisoblanadi (C# bilan taqqoslasa object sinfi bilan mos tushadi). Station classidan sinflar ierarxiyasi boshlanadi. seedlinkreader shu ierarxiyaning bir qismi.
seedlinkreaderning vazifasi: Mijoz(Stansiya) ma'lumotlarni ma'lum algoritm bo'yicha zichlaydi va shu bo'yicha paketlarga bo'lib jo'natib turadi. Har bir paket 512 bayt. Zichlash algoritmi seedlink deb nomlanadi. seedlinkreader classida zichlangan ma'lumotlar algoritm bo'yicha o'z xoliga qaytariladi.
Station.seedlinkreader.IsConnected esa bool turida qiymat qaytaruvchi funksiya, ya'ni shu stansiya bilan aloqa bor yoki yo'qligini tekshiradi

4) Dastur ishga tushganda fayldan stansiyalar haqida ma'lumotlar(ip,port, stansiya nomi va h.k.)ni
o'qib oladi va listga yig'adi. Keyin quyidagi funksiya bajariladi:

public void StartStations()
        {
            if (liststation.Count != 0)
            {
                foreach (Station station in liststation)
                {
                    station.stationform.StartStation();
                }
            }
        }


station.stationform.StartStation() - funksiyasi quyidagicha:

public void StartStation()
        {
            Station.network = "TA";
            Station.station = "*";
            Station.location = SeedlinkReader.EMPTY;
            Station.channel = "BHZ";
            Station.start = SeedlinkReader.EMPTY;
            Station.end = SeedlinkReader.EMPTY;
            Station.maxRecords = 10;
            Station.timeoutSeconds = SeedlinkReader.DEFAULT_TIMEOUT_SECOND;
            Station.infoType = SeedlinkReader.EMPTY;
            Station.ioutFile = SeedlinkReader.EMPTY;
            Station.verbose = false;
            Station.dos = null;
            chart1.Series[0].Points.Clear();
            Station.IsWorking = false;
            thread = new Thread(ForThread);
            isconnectionfailedthread = new Thread(ForIsConnectionFailedThread);
            pointcount = 0;
            chart1.ChartAreas[0].AxisX.Minimum = 0;
            chart1.ChartAreas[0].AxisX.Maximum = 3600;
            chart1.ChartAreas[0].AxisX.Interval = 1;
            isfullchartarea = true;
            isconnectionfailedthreadint = 0;
                if (Station.seedlinkreader.initConnection())
                {
                    thread.Start();
                }
                else
                {
                    UpdateStation();
                }
        }

thread.Start() - bo'lganda oldingi izohda qoldirgan ForThread() funksiyasi ishni boshlaydi.
UpdateStation() - stansiya ishga tushmasa bu haqida xabar berish uchun yozilgan funksiya.


liststation o'zgaruvchisida nechta count bo'lsa, ya'ni nechta stansiya mavjud bo'lsa har birida thread.Start() bo'ladi va ma'lumotlarni qabul qilishni boshlaydi.



Katta rahmat !
izoh qoldirdi 20 dekabr, 17 m.kholmirzaev (164 bal)
Ha gapni mana bu yog'dan boshlash kerak edi. Siz mijoz, stationlar esa Server. Ya'ni siz stationlarga murojaat qilasiz va ulardan ma'lumotlarni olib  bazaga saqlab qo'yasiz. To'g'ri tushundimmi? Mana buni misol sifatida yozdim o'zingizga moslab ko'chirib olasiz:

    public class ConnectionInfo
    {
        public ConnectionParam ConnectionParam { get; set; }

        public Station Station { get; set; }

        public Thread Thread { get; set; }

        public DateTime CreatedDateTime { get; set; }
        
    }

    public class Station
    {
        private Ping ping;

        public Station(ConnectionParam param)
        {
            IpEndPoint = new IPEndPoint(param.IpAddress, param.Port);
            ping = new Ping();
        }
        
        public IPEndPoint IpEndPoint { get; private set; }

        public bool IsConnected { get { throw new NotImplementedException();} }

        public byte[] GetData() => throw new NotImplementedException();

        public void Open() => throw new NotImplementedException();

        public bool PingNetwork()
        {
            var result = ping.Send(IpEndPoint.Address);
            return result != null && result.Status == IPStatus.Success;
        }
    }

    public struct ConnectionParam
    {
        public ConnectionParam(string line)
        {
            if(string.IsNullOrEmpty(line) || line.Count(x=>x.Equals(';')) == 0)
                throw new Exception("Error reading params. Please check config file.");

            var data = line.Split(';');
            if(data.Length < 2)
                throw new Exception("Error reading params. Please check config file.");

            IpAddress = IPAddress.Parse(data[0]);
            Port = int.Parse(data[1]);
        }

        public IPAddress IpAddress { get; private set; }

        public int Port { get; private set; }
    }
    // aloqalar menedjeri
    public class StationsManager
    {
        // internet ulanganmi yo'qmi tekshirib ko'radi.
        protected bool Connection { get; set; } = false;

        // stationlarga ulanish parametrlari
        private ICollection<ConnectionParam> _params;

        // o'rnatilgan aloqalar
        private ICollection<ConnectionInfo> _connections;

        // o'rnatilgan aloqalar ro'yxatini olish
        public IEnumerable<ConnectionInfo> GetConnections()
        {
            return _connections;
        }
        
        public StationsManager(ICollection<ConnectionParam> connectionParams)
        {
            _connections = new List<ConnectionInfo>();
            _params = connectionParams;
        }

        // run
        public void Start()
        {
            InitThreads(_params);
        }

        // oqimlarni ishga yaratish va ishga solish
        private void InitThreads(ICollection<ConnectionParam> connectionParams)
        {
            try
            {
                foreach (var connectionParam in connectionParams)
                {
                    var station = new Station(connectionParam);

                    // har bir stationni ipmanziliga ping berib ko'ramiz.
                    if (!station.PingNetwork())
                    {
                        Console.WriteLine($"Warning: Connecting to {station.IpEndPoint} failed.");
                    }
                    else
                    {
                        // station bilan aloqa o'rnatish
                        station.Open();

                        var thread = new Thread(()=> StationReader(station));

                        // o'rnatilgan aloqa haqida ma'lumot
                        var info = new ConnectionInfo()
                        {
                            Thread = thread,
                            Station = station,
                            ConnectionParam = connectionParam,
                            CreatedDateTime = DateTime.Now
                        };

                        _connections.Add(info);
                        
                        thread.Start();
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        
        public void StationReader(Station station)
        {
            while (true)
            {
                try
                {
                    if (station.IsConnected)
                        station.GetData();
                    // bu yerga hamma kerakli amallaringiz yozaverasiz.
                }
                catch (Exception e)
                {
                    Ping ping = new Ping();

                    var result = ping.Send(station.IpEndPoint.Address);
                    if (result == null || result.Status != IPStatus.Success)
                        Console.WriteLine($"Error conneting to {station.IpEndPoint}");
                    else
                        Console.WriteLine($"Warning: {e}");
                }
            }
        }
    }
izoh qoldirdi 23 dekabr, 17 SARVARBEK (355 bal)
Juda to'g'ri tushunibsiz. Respublika bo'ylab stansiyalar o'rnatib chiqilgan. Har birida ip, nomi va shunga o'xshash ma'lumotlari bor. Mening qiladigan ishim shularga ulanib ulardan keladigan ma'lumotlarni qayta ishlashdan iborat, hamda bu jarayon to'xtamasligi kerak.

Vaqtizni ayamasdan kodini yozganiz uchun katta rahmat. Man o'zimni dasturimni shunga moslab o'zgartirib chiqaman. Lekin bitta narsani so'ramoqchi edim.
Siz yozgan metodda ham thread ishlatilgan ekan, bu yana dasturni sust ishlashiga olib kelmaydimi, yoki siz shu yo'l bilan o'zizni dasturizdagi muammoni hal qilganmisiz? Aytmoqchimanki, hozirgi mani vaziyatim uchun optimal yechim shumi?
izoh qoldirdi 19 yanvar, 18 m.kholmirzaev (164 bal)
To'g'ri yechim deb hisoblayman. Threadlarni uzoq vaqt ishlash talab etiladigan ishlarda ko'p qo'llayman. Task/async/await larni asosan qisqa vaqt ichida bajariladigan holatlarda ishlataman.

Assalomu alaykum, yordam.uz saytimizga xush kelibsiz.

Bu saytda o`zingizni qiziqtirgan savollarga javob olishingiz va o`z sohangiz bo`yicha savollarga javob berishingiz mumkin.

Bizning Oilamizga a'zo bo`lganingiz uchun chuqur Minnatdorchilik bildiramiz !!!

Telegram kanal YordamUzRss

...