Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Wątki przy sprawdzaniu sumy md5 plików


Rekomendowane odpowiedzi

Opublikowano
Siema, co prawda ten temat powinien być w dziale C# ale takowego nie znalazłem. Mam problem z zawieszeniem się programu na czas sprawdzania sum md5 plików.
Program wygląda tak :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Security.Cryptography;
using System.Net;
using System.Threading;
using System.Diagnostics;


namespace patcher
{
    public partial class MainWindow : Window
    {
        // Zmienne globalne
        public static List<string> filesToDownload = new List<string>();
        public static int licznik_listy = 1;
        public Stopwatch sw = new Stopwatch();
        public int licz = 0;


        public MainWindow()
        {
            InitializeComponent();
            // Sprawdzanie czy istnieją foldery, jeżeli nie to je tworzy
            string[] directories = { "pack", "lib", "miles", "screenshot" };
            foreach (string directory in directories)
            {
                if (Directory.Exists(@System.AppDomain.CurrentDomain.BaseDirectory + directory) == false)
                {
                    debuk.Text += "\nNie znalazłem folderu \"" + directory + "\" więc go tworzę."; //Dodanie do TextBox'a informacji co sie dzieje 
                    Directory.CreateDirectory(directory);
                }
            }


            WebClient webClient = new WebClient();
            webClient.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(SprawdzaniePlikow);
            webClient.DownloadFileAsync(new Uri("http://localhost/md5_plikow"), "md5_plikow"); // Pobranie pliku z nazwami plików i sumami MD5 z serwera
        }

        void SprawdzaniePlikow(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // Jeśli pobierze ten plik to rozpoczyna sprawdzanie
        {
            MessageBox.Show("Sprawdzone zostaną są sumy kontrolne plików\nKliknij ok i czekaj");
            string[] files = File.ReadAllLines(@System.AppDomain.CurrentDomain.BaseDirectory + "md5_plikow"); // Tworzy tablice z pobranego pliku
            File.Delete(@System.AppDomain.CurrentDomain.BaseDirectory + "md5_plikow"); // Po zrobieniu tablicy usuwa go

            foreach (string actualFile in files)
            {
                licz++;
                if (actualFile != "")
                {
                    string[] file = actualFile.Split('|'); // Spiltowanie tablicy utworzonej z pobranego pliku
                    string fileName = file[0]; // nazwa pliku
                    string fileMD5 = file[1]; // suma md5 pliku
                    string result;

                    if (File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + fileName))   // sprawdzam czy plik istnieje
                    {
                        using (var md5 = MD5.Create())  // sprawdzam sumę MD5 pliku
                        {
                            using (var stream = File.OpenRead(@System.AppDomain.CurrentDomain.BaseDirectory + fileName))
                            {
                                result = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
                            }
                        }

                        if (result != fileMD5)  // jeżeli sumy MD5 się nie zgadzają
                        {
                            debuk.Text += "\nMD5 pliku " + FiltracjaSciezki(fileName) + " nie zgadza się."; // Dodanie nazwy pliku TextBox'a z "Debugowaniem"
                            lista_plikow.Text += "\n" + FiltracjaSciezki(fileName); // Dodanie nazwy pliku do TextBox'a 
                            filesToDownload.Add(FiltracjaSciezki(fileName)); // Dodanie do listy plików jakie trzeba pobrać
                        }
                    }
                    else // jeżeli plik nie istnieje
                    {
                        debuk.Text += "\n Plik \"" + FiltracjaSciezki(fileName) + "\" nie istnieje."; // Dodanie nazwy pliku TextBox'a z "Debugowaniem"
                        lista_plikow.Text += "\n" + FiltracjaSciezki(fileName); // Dodanie nazwy pliku do TextBox'a 
                        filesToDownload.Add(FiltracjaSciezki(fileName)); // Dodanie do listy plików jakie trzeba pobrać
                    }
                }

                if (files.Length == licz) // Jeśli pętla wykona się tyle razy ile miało sprawdzić plik
                {
                    __procent.Content = "Zakonczylem sprawdzanie plików."; //Informacja
                    download(filesToDownload[0]);  // Rozpoczyna pobieranie pierwszego pliku
                }
            }
        }

        string FiltracjaSciezki(string tekst) //Zamiana ścieżki na samą nazwę pliku
        {
            StringBuilder S = new StringBuilder(tekst);
            S.Replace(@System.AppDomain.CurrentDomain.BaseDirectory, "");
            return S.ToString();
        }

        void download(string tekst) //Pobieranie pliku
        {
            WebClient webClient = new WebClient();
            webClient.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(webClient_DownloadFileCompleted);
            webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
            webClient.DownloadFileAsync(new Uri("http://localhost/" + tekst), tekst);
            sw.Start();
        }

        void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) //Informacje o pobieraniu
        {
            __procent.Content = "Pobrano już: " + e.ProgressPercentage.ToString() + "%";
            __predkosc.Content = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
            __pobrano.Content = string.Format("{0} MB's / {1} MB's", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
        }

        void webClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) //Gdy już pobierze plik
        {
            sw.Reset();
            if (filesToDownload.Count > licznik_listy) // Sprawdzanie ile już pobrało plików
            {
                download(filesToDownload[licznik_listy]); // Pobranie następnego pliku z listy
                debuk.Text += "\nZakończono pobieranie pliku: " + filesToDownload[licznik_listy]; // Wyświetlenie info w oknie "Debugowania"
                licznik_listy++;
            }
            else // Jeżeli pobrało wszystkie to  zakańcza
            {
                _1.Content = "Aktualizacja plików przebiegła pomyślnie";
            }
        }








        //Jeśli kliknę w obrazek to zakończy program
        private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Application.Current.Shutdown();
        }
    }
}

Próbowałem odpalić sprawdzenie plików:
 

void SprawdzaniePlikow(object sender, System.ComponentModel.AsyncCompletedEventArgs e)

w osobnym wątku lecz po sprawdzeniu plików chcę go przerwać, powrócić do wątku głównego i rozpocząć pobieranie plików.
 
Dlaczego?
Otóż odpowiedź jest prosta, gdy chcę np. zmienić zawartość TextBox'a w nowo stworzonym wątku to nie mogę ponieważ nie ma do niego dostępu
 
Czy ktoś ma pomysł jak uporać się z tym problemem?
 
 
PS. Program to typowy aktualizator plików ;]

8910814572903361049127.png

  • 1 miesiąc temu...
Opublikowano

Bardzo prosty kod umieszczony poniżej:

this.Invoke(new MethodInvoker(delegate
{
//kod np. textbox1.text = null;
}));
Opublikowano

Obliczanie md5 oraz pobieranie plików powinieneś robić na wątku 'w tle'. Na tym wątku tworzysz sobie cały 'scenariusz', czyli np pobranie informacji o zdalnych plikach, obliczenie md5 plików lokalnych, ewentualny download.

Wątek główny ma być tylko i wyłącznie do GUI, jakakolwiek długotrwała operacja wykonana na nim spowoduje 'zamrożenie się' okna aplikacji(program nie odpowiada itp).

Jak kolega wyżej wspomniał, istnieje możliwość 'przełączenia się' na główny wątek, wywoływany metodą Invoke obiektu utworzonego na głównym wątku, tylko w Invoke możesz modyfikować zawartość okna. Tam więc umieszczasz kod odpowiedzialny za włączenie/wyłączenie przycisków na oknie, aktualizację paska postępu (np podczas ściągania plików) itp.

pasek_4oo_6o.jpg

Aktualny poziom zła: 75 punktów ostrzeżeń.
Achievements:
  • 22 zajebiste posty oznaczone czerwonym kółeczkiem
  • 1 urażony modek - dwa razy! (Istny Diabeł)
  • 4365 userów forum, którym powiedziałem smutną prawdę
Opublikowano

Obliczanie md5 oraz pobieranie plików powinieneś robić na wątku 'w tle'. Na tym wątku tworzysz sobie cały 'scenariusz', czyli np pobranie informacji o zdalnych plikach, obliczenie md5 plików lokalnych, ewentualny download.

Wątek główny ma być tylko i wyłącznie do GUI, jakakolwiek długotrwała operacja wykonana na nim spowoduje 'zamrożenie się' okna aplikacji(program nie odpowiada itp).

Jak kolega wyżej wspomniał, istnieje możliwość 'przełączenia się' na główny wątek, wywoływany metodą Invoke obiektu utworzonego na głównym wątku, tylko w Invoke możesz modyfikować zawartość okna. Tam więc umieszczasz kod odpowiedzialny za włączenie/wyłączenie przycisków na oknie, aktualizację paska postępu (np podczas ściągania plików) itp.

 

 

Bardzo prosty kod umieszczony poniżej:

this.Invoke(new MethodInvoker(delegate
{
//kod np. textbox1.text = null;
}));

Dzięki tego mi było trzeba :D Poprawię kod patchera

8910814572903361049127.png

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...