Biblioteka dll a wielowątkowość

0

Cześć,

powiedzmy że jest taka sytuacja: potrzebuję wydrukować np. 100 stron. Przygotowanie takiego wydruku trochę trwa. Nie chciałbym jednak blokować głównej aplikacji. Czy rozwiązanie z biblioteką dll która będzie zajmować się przygotowaniem danych oraz ich wydrukiem (wszystko przy użyciu fast report) rozwiąże problem?
Główna aplikacja wysyła rozkaz wydruku i wraca do normalnej pracy a cały proces wydruku odbywać się będzie przy użyciu biblioteki.

Czy takie coś będzie działać?

2

A dlaczego tego nie mógłby robić Main w innym wątku ?
Widzę, że odcięcie problemu robisz gdzie nie tzreba, na szczegółach implementacyjnych a nie istocie. DLL ma niewiele do tak postawionego zagadnienia.

0

Wielowątkowość to pierwsze co zrobiłem i to na dwa sposoby: biblioteką PPL a następnie "normalnymi" wątkami. Niestety jest pewien problem o którym nie wspomniałem w pierwszym poście bo nie było to kwestią mojego pytania. W skrócie chodzi o fastreport oraz jego lekki problem z pracą równoległą (a dokładnie ze współdzieleniem danych). Może na razie nie wchodźmy w to, bo nie jest to głównym wątkiem tego tematu (jak będziecie chcieli to coś więcej o tym napiszę).

Dlatego ponawiam pytanie: czy taki sposób drukowania przez dll będzie traktowany jak osobny wątek z punktu widzenia systemu operacyjnego?

0

To nie raportujesz z baz SQL? Wygląda jakbyś dane brał z plików? Dzielnie jakich danych jest problematyczne?
Dużo tu brakujacych szczegółów.

Wątek ma dwa/trzy sensy: wątek w języku programowania, w systemie, i w procesorze.
Wątek systemowy jest bytem "prawie niewidzialnym" w tym sensie, że bardzo niewiele systemowego API od tego zależy, ma trochę stosu - oprócz tego że większość API jest w "jakimś" wątku.
Za to DLLka jest dość istotnym, np ma samodzielną gospodarkę pamięcią, pewnie by miała własne handlery plików (tu trochę gdybam)

5

Jak wywołasz funkcję z DLL w wątku głównym efekt będzie taki sam jakby kod funkcji był właśnie w głównym wątku aplikacji a jak to zrobisz w wątku pobocznym to będzie tak jak by kod był w poboczny. Po prostu biblioteka DLL kompletnie NIC tu pod tym względem nie zmienia. Zajmij się problemem synchronizacji, który według Ciebie występuje gdy drukujesz w wątku pobocznym, bo to trzeba rozwiązać.

0

Oczywiście dane pobieram z baz. Główny wątek ma tylko wywoływać wydruk, przekazując jakieś tam parametry, np. numer rekordu nagłówka dokumentu a reszta już ma się wykonywać w tle.

Dlaczego tak mocno się uwziąłem na "rozdzielenie" wydruku od głównego programu? A no dlatego że tak naprawdę drukuję raport oraz jego kopię na innej drukarce (termicznej). Okazało się że fast report po wydruku tak jakby psuje dane i trzeba odczekać troszkę czasu (około 200 ms na linię raportu a tak naprawdę na fizyczne wydrukowanie raportu, niestety nie ma w fast report funkcjonalności która mogłaby sprawdzić czy wydruk już się ukończył) aby można było puścić ten sam raport na inną drukarkę.
Jako że fast report jest "odporny" na wątki ze względu na pewne współdzielenie danych (jak pisałem powyżej) to wymyśliłem sobie że pierwszy wydruk mogę nawet zrobić normalnie z głównego programu (w końcu nie trzeba czekać na wydruk a tylko na załadowanie danych do spoolera) ale przed uruchomieniem następnego wydruku trzeba będzie poczekać troszkę czasu a klient za bardzo nie chce czekać. Dlatego wymyśliłem sobie że to co jest w dll-ce być może jest traktowane jako całkiem zewnętrzny program i tamte wystąpienie fast reportu nie będzie wpływać na moje z głównego programu.
Po prostu wywołam odpowiednią procedurę w dll-ce i reszta mnie nie interesuje.

Ale czy to zadziała? Pytam bo być może ma ktoś doświadczenia?

0
kAzek napisał(a):

Jak wywołasz funkcję z DLL w wątku głównym efekt będzie taki sam jakby kod funkcji był właśnie w głównym wątku aplikacji a jak to zrobisz w wątku pobocznym to będzie tak jak by kod był w poboczny. Po prostu biblioteka DLL kompletnie NIC tu pod tym względem nie zmienia. Zajmij się problemem synchronizacji, który według Ciebie występuje gdy drukujesz w wątku pobocznym, bo to trzeba rozwiązać.

O widzisz, zanim opisałem problem chyba dostałem odpowiedź. Czyli nie tędy droga raczej.

Czyli powiedzmy całkiem teoretycznie:
w wątku głównym programu wywołuję funkcję z dll test która robi Sleep(5000) - która blokuje normalnie program a następnie ShowMessage('odblokowano').
rozumieć mam że aplikacja będzie zablokowana na 5 sekund a następnie po tym czasie pokaże się komunikat. Czy też normalnie będzie działać a po 5 sekundach pojawi sie komunikat?

3

Tak, zablokuje się na 5 sekund.

dll nie ma nic do tego czy główny wątek się zablokuje czy nie. A Twój problem jest gdzie indziej - w pobieraniu danych jak sam napisałeś

0

Ok, odpowiedź otrzymałem. Wniosek, nie tędy droga.
Zrobię to osobnym exekiem który będzie czymś w rodzaju serwera wydruku i już.

Dzięki za odpowiedź.

1

Oj dawno nie używałem FR ale coś tam jeszcze pamiętam. Ja realizowałem to tak:

  1. Dane do raportu przekazywałem z aplikacji aby każda instancja raportu nie odpalała tego samego zapytania po stronie samego pliku FR3- normalnie przekazujesz dataseta.

  2. FR z tego co pamiętam musi mieć swoją instancję więc ja u siebie miałem klasę, która miała zawierała wewnętrzny licznik instancji danej klasy. Ponadto sama funkcja EXECUTE ubrana również była w wątek więc technicznie każde wywołanie FR miało swoją instancję, w swoim wątku dzięki czemu jednocześnie szedł wydruk na kilka drukarek.

Niestety gotowego kodu u siebie nie mam bo było to robione w firmie ale z tego co pamiętam takie wielowątkowe wywołanie FR załatwiało wydruk jednocześnie na wielu drukarkach.

Co do samego pomysłu z takim "print serwerem" to teorytycznie też załatwi temat ale jest to moim zdaniem nieeleganckie rozwiązanie ;)

1
woolfik napisał(a):

Oj dawno nie używałem FR ale coś tam jeszcze pamiętam. Ja realizowałem to tak:

  1. Dane do raportu przekazywałem z aplikacji aby każda instancja raportu nie odpalała tego samego zapytania po stronie samego pliku FR3- normalnie przekazujesz dataseta.

Ja tak nie robię, wolę mieć świeże dane do wydruku.
Ale to trochę taka moja specyfika, informacje zmieniają się w zastraszającym tempie ;-)

  1. FR z tego co pamiętam musi mieć swoją instancję więc ja u siebie miałem klasę, która miała zawierała wewnętrzny licznik instancji danej klasy. Ponadto sama funkcja EXECUTE ubrana również była w wątek więc technicznie każde wywołanie FR miało swoją instancję, w swoim wątku dzięki czemu jednocześnie szedł wydruk na kilka drukarek.

Tak, ale to nie koniec:
https://www.fast-report.com/pl/faq/13/98/

Niestety gotowego kodu u siebie nie mam bo było to robione w firmie ale z tego co pamiętam takie wielowątkowe wywołanie FR załatwiało wydruk jednocześnie na wielu drukarkach.

Co do samego pomysłu z takim "print serwerem" to teorytycznie też załatwi temat ale jest to moim zdaniem nieeleganckie rozwiązanie ;)

Dlaczego nieeleganckie?
A poza tym, jest przecież FastReport Server ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1