1. Гость, мы просим Вас ознакомиться с Правилами Форума и Отказом от ответственности!

Рекурсивный метод проверки файлов на изменения

Тема в разделе '.NET', создана пользователем Fituchini, 20 янв 2020.

  1. TopicStarter Overlay

    Fituchini Пользователи

    Сообщения:
    339
    Лайки:
    71
    Пол:
    Мужской
    Репутация:
    0
    Команда:
    PWAA
    Страна:
    Russian Federation Russian Federation
    Всем привет. Подскажите пожалуйста такую вещь.
    Перед выпуском патча игры создаю БД (sqlite) файлов внутри папки.
    У каждого файла проверяю имя, размер и узнаю MD5
    Перед запуском игры проверяю файлы на наличие изменений.
    PHP:

     
    private string ComputeMD5Checksum(string path)
            {
                
    using (FileStream fs File.OpenRead(path))
                {
                    
    MD5 md5 = new MD5CryptoServiceProvider();
                    
    byte[] fileData = new byte[fs.Length];
                    
    fs.Read(fileData0, (int)fs.Length);
                    
    byte[] checkSum md5.ComputeHash(fileData);
                    
    string result BitConverter.ToString(checkSum).Replace("-"String.Empty);
                    return 
    result;
                }
            }
    private 
    void ListFiles()
            {
                try
                {
                    
    path Path.Combine(path"Data");
                    var 
    dir = new DirectoryInfo(path);
                    
    int qt dir.GetFiles("*.*"SearchOption.AllDirectories).Length;
                    
    BeginInvoke((MethodInvoker)(() => { progressBar1.Maximum qt; }));

                    foreach (var 
    files in dir.GetFiles("*.*"SearchOption.AllDirectories))
                    {
                        
    BeginInvoke((MethodInvoker)(() => { lProgr.Text files.Name; }));

                        
    db_con DBCON = new db_con();
                        
    cmd_db = new SQLiteCommand("Select * FROM files WHERE FName='" files.Name "'"DBCON.GetConnection());
                        
    rdr_db cmd_db.ExecuteReader();
                        
    string DBName "";
                        
    int Size 0;
                        
    string MDS "";
                        while (
    rdr_db.Read())
                        {
                            
    DBName rdr_db[0].ToString();
                            
    Size Convert.ToInt32(rdr_db[1].ToString());
                            
    MDS rdr_db[2].ToString();
                        }
                        
    DBCON.CloseConnection();
                        if (
    ComputeMD5Checksum(files.FullName) != MDS)
                        {
                            List<
    stringerr = new List<string>();
                            
    err.Add("Create time " DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + "\r" files.Name " in DB " DBName "\rLength loc - " files.Length +
                                
    " in DB " Size "\rMD5 loc - " ComputeMD5Checksum(files.FullName) +
                                
    " in DB " MDS Environment.NewLine +
                                
    "//=======================================================================================//" +
                                
    Environment.NewLine);
                            
    File.AppendAllLines(@"acd.log"err);
                        }
                        
    BeginInvoke((MethodInvoker)(() =>
                        {
                            
    progressBar1.Value++;


                        }));
                        
    _d++;
                        
    BeginInvoke((MethodInvoker)(() => { lblPerc.Text = ((_d 100) / qt).ToString() + "%"; }));
                        if (
    _d > (qt 2))
                        {
                            
    BeginInvoke((MethodInvoker)(() => { label1.Text "Начинаем подготовку к упаковке"; }));
                        }
                        if (
    _d > (qt - (qt 4)))
                        {
                            
    BeginInvoke((MethodInvoker)(() => { label1.Text "Почти закончили"; }));
                        }
                    }
                   
                }
                catch (
    Exception ex)
                { 
    MessageBox.Show(ex.Message"Error"MessageBoxButtons.OKMessageBoxIcon.Error); Application.Exit(); }
                try
                {

                    
    Process GameClient = new Process();
                    
    string pathClient Path.Combine(Application.StartupPath.ToString(), "Game.exe");

                    
    GameClient.StartInfo.FileName pathClient;
                    
    //GameClient.StartInfo.ErrorDialog = true; //auto show errors
                    
    GameClient.Start();
                    
    //Запускаем клиент!!!

                    //Бесконечный поток жрёт много CPU
                    //Делаем в таймере раз в 30 секунд
                    //BeginInvoke((MethodInvoker)(() => { Thread.Sleep(3000); Silent(); }));
                    
    tmrAntiCheat.Start();
                  
    // Invoke((MethodInvoker)(delegate { this.Visible = false; }));
                   
                    //Запускаем проверку в бесконечном потоке.
                   
                
    }
                catch (
    Exception ex)
                {
                    
    /*close window*/

                    
    BeginInvoke((MethodInvoker)(() => {
    #if DEBUG
                        
    MessageBox.Show(ex.ToString());
    #endif
                        
    label1.Text "Ошибка! " ex.Message " Game.exe"tmrClose.Start();
                    }));

                }
            }
    Весь код работает хорошо.
    Но вот теперь задача, можно ли как то сделать так, чтобы программа запускалась только на менее загруженных ядрах? Если конечно такие есть.
    Хоть проверка и занимает пару секунд у меня, не факт что она будет занимать тоже время и у другого игрока.
    Хочется сделать процесс менее заметным
  2. alexdnepro Эксперт AngeliCore Пользователи Open Source Contributor White List

    Сообщения:
    754
    Лайки:
    1.313
    Пол:
    Мужской
    Репутация:
    6
    Если хочется сделать проверку без зависаний, стоит запускать её в отдельном потоке на фоне, не блокируя основной.
    Fituchini нравится это.
  3. Шифер Пользователи

    Сообщения:
    32
    Лайки:
    10
    Пол:
    Мужской
    Репутация:
    0
    Так если программа будет работать в двух потоках, то клиент запустится раньше, чем пройдет нужная проверка и это(наверное) плохо.
  4. un712 Пользователи

    Сообщения:
    53
    Лайки:
    13
    Репутация:
    0
    md5 замени на xxhash и забудь про CPU. Узким местом станет жесткий.
    Fituchini нравится это.
  5. TopicStarter Overlay

    Fituchini Пользователи

    Сообщения:
    339
    Лайки:
    71
    Пол:
    Мужской
    Репутация:
    0
    Команда:
    PWAA
    Страна:
    Russian Federation Russian Federation
    Если проверка не пройдена, то есть используется некая модификация файла, и программа будет убивать процесс клиента игры.
    Если клиент не найдётся в течении 30 секунд, программа закроется.
    Если клиент игры не найдёт "проверяльщика файла" то клиент не будет запускаться.
    Так же клиент игры запускается с рандомным ключом, "Проверяльщик файла" знает какой ключ передать клиенту игры перед запуском. А клиент игры знает все "положительные" ключи.
    И опять же, если ключ не найден или используется не настоящий ключ, клиент не запустится
  6. alexdnepro Эксперт AngeliCore Пользователи Open Source Contributor White List

    Сообщения:
    754
    Лайки:
    1.313
    Пол:
    Мужской
    Репутация:
    6
    Она может работать и с куда большим количеством потоков, главное их правильно синхронизировать и продумать. И само собой сделать ожидание завершения всех процессов перед возможностью запуска клиента
  7. namerand0m Пользователи

    Сообщения:
    10
    Лайки:
    3
    Пол:
    Мужской
    Репутация:
    0
    Команда:
    A
    Как правило файловая система это ресурс который плохо параллелится, если есть уверенность, что функция хеширования (cpu bound) несет ощутимую задержку по сравнению с io-bound операциями, то возможно в этом случае можно задуматься о распараллеливании.
    Вынести в отдельное ядро едва ли сможет решить проблему, так же как вряд ли вы найдете ядро с наименьшей нагрузкой, т.к. тредпул и диспечератор винды равномерно распределяет нагрузку по потокам. Еще бы посоветовал сделать IO-операции асинхронными, чтобы не лочить поток на время пока операционная система вернет данные с файла.
    В вашем случае самый очевидный вариант это вынести проверку файлов в отдельный поток и уведомлять пользователя уже после запуска клиента и убивать тот же клиент, если есть такое требование.
  8. Шифер Пользователи

    Сообщения:
    32
    Лайки:
    10
    Пол:
    Мужской
    Репутация:
    0
    Сложные вещи вы говорите, но работу программы с hdd диском ты никак не ускоришь. Если идет работа именно с cpu, то лучше довериться ОС, чем пытаться распределять нагрузку(мое мнение). Можно много чего сломать работая на прямую с железом.
  9. Waspas Пользователи

    Сообщения:
    2
    Лайки:
    0
    Пол:
    Мужской
    Репутация:
    0
    Команда:
    MMg-pro
    Страна:
    Tajikistan Tajikistan
    Сейчас все массово на ssd переходят. Правда там и мощность поболее нужна но это тоже легко устраняется. Но ускорение все таки заметно и хорошо заметно
Черновик сохранён Черновик удалён
Similar Threads
  1. Fituchini
    Ответов:
    1
    Просмотров:
    1.421
  2. default
    Ответов:
    3
    Просмотров:
    1.035
  3. MrViper
    Ответов:
    11
    Просмотров:
    1.618
  4. JoLan
    Ответов:
    5
    Просмотров:
    3.048
  5. california
    Ответов:
    6
    Просмотров:
    2.229
Загрузка...

Поделиться этой страницей