Próbowałem dostać to, co uważam za najprostszą możliwą formę wątkowania do pracy w mojej aplikacji, ale po prostu nie mogę tego zrobić.C# Threading - Czytanie i mieszanie wielu plików jednocześnie, najłatwiejszą metodą?
Co chcę zrobić: Mam główny formularz z paskiem stanu i paskiem postępu na nim. Muszę przeczytać coś pomiędzy 3 a 99 plikami i dodać ich skróty do napisu [], który chcę dodać do listy wszystkich plików z ich odpowiednimi skrótami. Następnie muszę porównać pozycje z tej listy z bazą danych (która jest dostępna w plikach tekstowych). Po wykonaniu wszystkich czynności, muszę zaktualizować pole tekstowe w formularzu głównym, a pasek postępu do 33%; głównie po prostu nie chcę, aby główna forma zamarzała podczas przetwarzania.
Pliki, z którymi pracuję, zawsze sumują się do 1,2 GB (+/- kilka MB), co oznacza, że powinienem móc odczytać je w bajcie [] s i przetworzyć je stamtąd (muszę obliczyć CRC32 , MD5 i SHA1 każdego z tych plików, więc powinno to być szybsze niż odczytanie ich wszystkich z dysku twardego 3 razy).
Należy również zauważyć, że niektóre pliki mogą mieć 1 MB, a inne mogą mieć 1 GB. Początkowo chciałem utworzyć 99 wątków dla 99 plików, ale to nie jest mądre, przypuszczam, że najlepiej byłoby ponownie użyć wątków małych plików, podczas gdy większe wątki plików nadal działają. Ale to brzmi dość skomplikowanie, więc nie jestem pewien, czy to też jest mądre.
Do tej pory próbowałem workerThreads i backgroundWorkers, ale nie wydają się działać zbyt dobrze dla mnie; przynajmniej praca w tle działała NIEKTÓRE czasu, ale nie potrafię nawet zrozumieć, dlaczego nie będą inne czasy ... tak czy inaczej główna forma wciąż zamiera. Teraz czytałem o Task Parallel Library w .NET 4.0, ale pomyślałem, że powinienem zapytać kogoś, kto wie, co robi, zanim zmarnuje więcej czasu.
Co chcę zrobić coś jak to wygląda (bez gwintu):
List<string[]> fileSpecifics = new List<string[]>();
int fileMaxNumber = 42; // something between 3 and 99, depending on file set
for (int i = 1; i <= fileMaxNumber; i++)
{
string fileName = "C:\\path\\to\\file" + i.ToString("D2") + ".ext"; // file01.ext - file99.ext
string fileSize = new FileInfo(fileName).Length.ToString();
byte[] file = File.ReadAllBytes(fileName);
// hash calculations (using SHA1CryptoServiceProvider() etc., no problems with that so I'll spare you that, return strings)
file = null; // I didn't yet check if this made any actual difference but I figured it couldn't hurt
fileSpecifics.Add(new string[] { fileName, fileSize, fileCRC, fileMD5, fileSHA1 });
}
// look for files in text database mentioned above, i.e. first check for "file bundles" with the same amount of files I have here; then compare file sizes, then hashes
// again, no problems with that so I'll spare you that; the database text files are pretty small so parsing them doesn't need to be done in an extra thread.
Czy ktoś będzie na tyle uprzejmy, żeby wskazać mi w dobrym kierunku? Poszukuję najłatwiejszego sposobu czytania i mieszania tych plików szybko (uważam, że haszowanie zajmuje trochę czasu, w którym można już odczytać inne pliki) i zapisać wynik na ciąg [], bez zamrożenia głównej formy, nic więcej , nic mniej.
Jestem wdzięczny za wszelkie dane wejściowe.
EDYCJA w celu wyjaśnienia: przez "backgroundWorkers pracujący przez pewien czas" Miałem na myśli, że (dla tego samego zestawu plików), być może pierwsze i czwarte wykonanie mojego kodu daje prawidłowy wynik, a UI odmawia w ciągu 5 sekund , dla drugiej, trzeciej i piątej realizacji blokuje formularz (i po 60 sekundach pojawia się komunikat o błędzie, że jakiś wątek nie odpowiedział w tym przedziale czasowym) i muszę przerwać wykonywanie przez VS.
Dziękuję za wszystkie sugestie i wskazówki, ponieważ wszyscy prawidłowo odgadliście, że jestem zupełnie nowy w tworzeniu wątków i będę musiał zapoznać się z opublikowanymi świetnymi linkami. Wtedy spróbuję tych metod i zaznaczę odpowiedź, która pomogła mi najbardziej. Dzięki jeszcze raz!
Co masz na myśli przez BackgroundWorker pracy na jakiś czas? Jeśli zostanie poprawnie zaimplementowany, przetwarzanie wykonywane w ramach BackgroundWorker nie powinno powodować zawieszania się formularza. – evasilchenko
Jeśli są na 1 dysku, potrzebujesz tylko 1 (dodatkowego) wątku. –
Ten artykuł może być pomocny dla Ciebie: http://www.hanselman.com/blog/BackToParallelBasicsDontBlockYourThreadsMakeAsyncIOWorkForYou.aspx –