Многопоточность C#

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Adio, 11 Jan 2016.

  1. Adio

    Adio Elder - Старейшина

    Joined:
    23 May 2005
    Messages:
    1,646
    Likes Received:
    148
    Reputations:
    18
    Нужен пример многопоточной программы на C# правильно реализованный.

    Потоки : 5
    Что делают: Обращаются к одному файлу, берут строку с удалением, записывают в другой файл.
    П.с что бы все было правильно реализованно, т.е потоки не мешали друг другу, занятость файла, и т д.
     
  2. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    Adio, а в чем профит чтения/записи одного файла в 5 потоков?
     
  3. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    могу предположить что это какая то лабораторная работа
     
  4. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    и вообще, что его там реализовывать, оберни разделяемый ресурс в lock(...) {}, делов то
     
  5. Adio

    Adio Elder - Старейшина

    Joined:
    23 May 2005
    Messages:
    1,646
    Likes Received:
    148
    Reputations:
    18
    Почти, просто си для меня темный лес, но кое что понимаю, так вот, нужно именно многопоточтое считывание, и сохранение.
    В принципе, уже не нужно, но если есть пример, буду рад, а так нашел тут много статей про реализацию многопоточности, я думал, все на много проще.. ) а там оказыется локи, критические секции и тётя раздающяя кирпичи.

    П.с дайте ссылки на скачивание книг этого распиаринного рихтера, почитаю, что бы понять, потом отдам.
     
  6. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Вот набросал кое-что, каждый тред читает строку из файла и пишет в другой, основной код:
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.IO;
    
    namespace ConsoleApplication7
    {
        class Program
        {
            static void Main(string[] args)
            {
                string txt_file = "C:\\users\\alex\\desktop\\1.txt";
                string out_file = "C:\\users\\alex\\desktop\\2.txt";
    
                string[] strings;
                thread_test thTest = new thread_test();
                thTest.file_name = out_file;
                try
                {
                    strings = File.ReadAllLines(txt_file);
                }
    
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return;
                }
                //пока висит флаг, будет работать цикл управления потоками         
                bool flag = true;
                int counter = 0;
                int dataCount = strings.Length;
    
    
                while (flag == true)
                {
                    if (counter >= dataCount)
                    {
                        flag = false;
                    }
    
                    while (thTest.nThreads < thTest.maxThreads)
                    {
                        if (flag == false)
                            break;
    
                        thTest.CreateThread(strings[counter]);
    
                        counter++;
                    }
    
                    thTest.WindUpThreads();
    
                    if (flag == false)
                    {
                        do
                        {
                            thTest.WindUpThreads();
    
                        } while (thTest.nThreads != 0);
                    }
    
                }//основной цикл
    
                Console.ReadKey();
    
            }//main
        }
    }
    
    И код класса с тредами:

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.Threading;
    using System.IO;
    
    namespace ConsoleApplication7
    {
        class thread_test
        {
    
            public List<Thread> threads = new List<Thread>();
            public int nThreads = 0;
            public int maxThreads = 5;
            public string file_name;
            public object obj = new object();
    
            public void DoWork(object data)
            {
    
                string mess = (string)data;
                Console.WriteLine("Дописываю строку "+ mess +" в файл");
                lock(obj)
                {
                    try
                    {
                        File.AppendAllText(file_name, mess + Environment.NewLine);
    
                    } catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
    
            }
    
            //создаем новый рабочий тред
            public void CreateThread(object data)
            {
                if (nThreads >= maxThreads)
                    return;
                Thread newThread = new Thread(DoWork);
                threads.Add(newThread);
                newThread.IsBackground = true;
                newThread.Start(data);
                nThreads++;
    
    
            }
    
            //закрываем завершенные треды
            public void WindUpThreads()
            {
                //MessageBox.Show("count: " + nThreads.ToString());
                for (int i = 0; i < threads.Count; i++)
                {
                    if (threads[i].IsAlive == false)
                    {
                        threads[i].Abort();
                        threads.RemoveAt(i);
                        //MessageBox.Show("removing at " + i.ToString());
                    }
    
                }
    
                nThreads = threads.Count;
            }
    
        }
    }
    

    Это все учебный вариант, в реальном проекте такое нужно еще приспособить к использованию. Например если сделать такое в гуи форме, то форма будет фризиться, потому что все время идет обработка цикла. Я правда не совсем понял, что значит "берут строку с удалением"? Если нужно каждую строку удалять, то нужно еще подумать. В любом случае, пример может пригодится.
     
  7. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Так нужно на си или на сишарпе?
     
  8. Adio

    Adio Elder - Старейшина

    Joined:
    23 May 2005
    Messages:
    1,646
    Likes Received:
    148
    Reputations:
    18
    На шарпе, вы вроде на шарпре и привели пример.
    Строка с удалением, это т.е поток берет строку, и затем удаляет ее, что бы другой поток брал другую строку, а не ту же самую. как то так.
    Просто нужна базовая фунция понимания такой работы потоков на простом примере.
     
  9. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Ну базовое понимание можно получить немного поизучав доки в гугле, наподобии вот этого http://metanit.com/sharp/tutorial/11.2.php ,а вот читать файл, удалять текущую строку и переходить к следующей в тем более многопоточном режиме задача не такая тривиальная. Но думаю у вас все получится.
     
  10. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    по мне это изврат полный, если уж надо читать файл построчно, лучше сделать отдельный поток, который будет управлять операциями с файлом и возвращать нужным потокам уже строку, а они уже пускай с ней творят что хотят, так же как и запись из потоков в другой файл, хотя у каждого свои взгляды :)
     
  11. Adio

    Adio Elder - Старейшина

    Joined:
    23 May 2005
    Messages:
    1,646
    Likes Received:
    148
    Reputations:
    18
    Я говорю что с Шарпом дело не имел, говорю как знаю - понимаю, я не знаю как лучше, я говрю как знаю.
    Но если есть вариант лучше то хорошо.
    Думал пойму, но как я понял, нужно учить азы, потому что мне не просто нужен готовый код, но я должен понимать как он работает от начала до конца.

    Допустим http://metanit.com/sharp/tutorial/11.2.php сдесь я понимаю логику, в моем понитии легче всего просто вставить :D, в две фунции, код (которые будет считывать из файла строку с удалением) т.е как бы два потока будут работать с одинаковым кодом (но так же там не все так просто) потому что они должны обращатся к 1 файлу, а там нужен лок, а если лок, то какой смысл в потоках тогда.. т.е если в общем логика не много линейна, из за того что нет базовых знаний как я думаю, что можно все упростить и избежать написания быдло кода, хотя быдлокод у всех думаю был по началу )
     
  12. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    В этом конкретном примере да, многопоточность излишня как уже говорили, хотя это вроде как распространенная показательная задача. Без локов никуда, это часть концепции. И про быдлокод верно. Все приходит с опытом, поэтому нет ничего постыдного в том чтобы сначала написать рабочий кривой код. Ведь с чего-то нужно начинать.
     
    #12 blackbox, 11 Jan 2016
    Last edited: 11 Jan 2016
  13. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    2 Adio, если хочешь действительно что-то знать не поверхностно, читай книги, например "Многоядерное программирование" Эхтера Ш., Робертс Дж.

    Все эти короткие статьи, ответы на stackoverflow и форумах, дают конкретное решение, без объяснения причин его принятия. Информацию в полном объеме можно почерпнуть только из книг.
     
    _________________________
    #13 Gar|k, 15 Jan 2016
    Last edited: 15 Jan 2016
  14. Adio

    Adio Elder - Старейшина

    Joined:
    23 May 2005
    Messages:
    1,646
    Likes Received:
    148
    Reputations:
    18
    Спасибо, это я уже понял, на счет стека, дело в том что нет пока что времени во все это вникать. Так как это просто мимолетная задача. Но посмотрев сам синтакс за пару дней, скажу что язык не особо сложный в понимании.
    Просто нужно учить с азов, и постепенно, а так приходится допонимать походу дела. Просто если бы дело было в консольном приложении, было бы на много проще, а так эти кнопки, события, и т д, есть моменты где просто не хватает знаний, в возможностях функционала..