Zakończenie Task'a

Zakończenie Task'a
BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

Witam,
mam problem z aplikacją.
Mianowicie mam uruchomiony Task i tam wykonują się pewne metody i funkcje, mam założony CancellationTokenSource, żeby po określonym czasie Task zakończył. Niestety przychodzi pewien czas kiedy aplikacja wisi na pewnej funkcji i może tak stać póki sam ją nie zrestartuje. CancellationTokenSource nie działa, nie kończy Task'a. Aplikacja jest serwisem więc bez sensu, kiedy muszę ręcznie ją restartować. Jest może jakiś sposób by aplikacja kończyła Task z automatu jak funkcja po pewnym czasie nie odpowiada?

AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:23 dni
0
bymbyn napisał(a):

CancellationTokenSource nie działa, nie kończy Task'a

Zdajesz sobie sprawę, że CancellationToken nie działa magicznie, tylko Task musi mieć w kodzie explicite sprawdzenie, czy trzeba się skończyć?

bymbyn napisał(a):

Jest może jakiś sposób by aplikacja kończyła Task z automatu jak funkcja po pewnym czasie nie odpowiada?

Nie ma, ponadto await lub ContinueWIth (jeżeli ich używasz) nie pozwalają na trywialne zrobienie tego. Najprościej jest odpalić drugie zadanko Task.Delay(timeout), a potem zrobić Task.WhenAny(firstTask, delayTask) i sprawdzić, który skończył się pierwszy.

Dygresja: jedną z podstawowych zasad pisania porządnego kodu wielowątkowego jest "zawsze czekaj z timeoutem". Jeżeli gdziekolwiek czekasz (czy to explicite przez Wait lub await, czy to implicite przez jakiś ContinueWith), zawsze ustawiaj timeout, bo inaczej kiedyś Cię to kopnie. Najlepiej jest to opakować w jakieś rozszerzenie i wtedy typowy kod asynchroniczny wygląda await Foo().ConfigureTimeout().ConfigureAwait(false), co wygląda paskudnie, ale przynajmniej robi robotę.

edytowany 1x, ostatnio: Afish
AK
  • Rejestracja:ponad 7 lat
  • Ostatnio:5 miesięcy
  • Postów:44
0

Tak jak wyżej napisał już ktoś, Cancellation token nie działa magicznie. Trzeba zarejestrować token source i zrobić jakiś warunek + sprawdzenie, żeby było wiadome co ma się stać gdy cancellation token będzie "wywołany". Tak naprawdę taki token możesz zastąpić zwykłym obiektem który zawiera sobie flagę bool stop = false; i w pętli sprawdzać czy nie została zmieniona na true a jeśli została to kończysz zadanie.

Poczytaj sobie o gracefull shutdown, fajnie jest coś takiego zaimplementować u siebie jak masz np Background Services w swojej apce i niektóre mogą zostać zamknięte z automatu a inne muszą poczekać na "dokończenie" aktualnie działąjących zadań z jakimś limitem czasowym

BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

#Afish dzięki za odpowiedź.
Ta metoda Task.WhenAny(firstTask, delayTask) robi to co mam robić i o to mi chodziło, jednak martwi mnie to że pierwszy Task nadal jest w pamięci i czeka na zakończenie, co skutkuje przyrostem użycia pamięci. Jest może sposób by, że tak się wyrażę, w sposób "perfidny" zabić ten Task?

AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:23 dni
0

Nie, nie można ubić Taska ot tak, co więcej, byłoby to bardzo złe.

BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

Czyli co jakiś tam czas będę musiał mój serwis ręcznie restartować by pozbyć się "śmieci" z pamięci.

Ok, dzięki #Afish za pomoc.
Wątek uważam za zakończony i rozwiązany

somekind
Użytkowników przyzywaj z @, a nie z #.
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

Jeśli Twój task się zawiesza albo powoduje wycieki pamięci, masz poważny błąd w kodzie - stwierdzenie dobra, będę se ten serwis restartował co godzinę nie jest rozwiązaniem i na 99% zaboli w przyszłości albo Ciebie, albo (co gorsza!) osobę, która po Tobie ten kod przejmie.

Wyobrażasz sobie, aby np. hydraulik Ci powiedział w dni parzyste, codziennie między piątą a szóstą rano musi pan uderzyć młotkiem w trzecią rurę, w połowie jej długości - w innym wypadku zaleje panu piwnicę, kwitując, że to dobrze wykonana robota?


edytowany 5x, ostatnio: Patryk27
BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0
Patryk27 napisał(a):

Jeśli Twój task się zawiesza albo powoduje wycieki pamięci, masz poważny błąd w kodzie - stwierdzenie dobra, będę se ten serwis restartował co godzinę nie jest rozwiązaniem i na 99% zaboli w przyszłości albo Ciebie, albo (co gorsza!) osobę, która po Tobie ten kod przejmie.

Wyobrażasz sobie, aby np. hydraulik Ci powiedział w dni parzyste, codziennie między piątą a szóstą rano musi pan uderzyć młotkiem w trzecią rurę, w połowie jej długości - w innym wypadku zaleje panu piwnicę, kwitując, że to dobrze wykonana robota?

To masz jakiś pomysł by zakończyć Task w którym jest funkcja z zewnętrznej biblioteki i ona stoi? Niestety do biblioteki nie mam dostępu.
Dokładnie chodzi o biblitekę ClaRUN. Jest tam funkcja AttachThreadToClarion(1); i na niej aplikacja mi stoi.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

W jakich warunkach się zawiesza?


edytowany 1x, ostatnio: Patryk27
BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

No właśnie trudno określić, przeważnie dzieje się to w nocy, mam podejrzenie, że może chodzić o baz danych, ale przed wywołaniem tej funkcji pytam bazę o dane i działa. Może też chodzić o jakiś serwis CDN, ale nie wiem jaki.

I wtedy mój serwis stoi póki go ręcznie nie zrestartuje

edytowany 1x, ostatnio: bymbyn
AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:23 dni
0

Zrób zrzut pamięci albo zapnij debugger i wstrzymaj aplikację, to zobaczysz wszystkie stosy.

Dygresja: Już wielokrotnie miałem sytuację, gdzie zewnętrzne biblioteki miały deadlocki, więc o ile rozwiązanie przez ubijanie taska nie jest eleganckie, to jednak w życiu bywa różnie.

BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

Też robiłem zrzut pamięci ale pokazało że stoi na AttachThreadToClarion(1); i nic więcej

AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:23 dni
0

No a co to znaczy? Co to dokładnie robi? Czym jest Clarion? Dlaczego nie może się doczekać?

BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

Co to robi to nie wiem, ale zgodnie z dokumentacją API "Przed pierwszym wywołaniem funkcji API dla każdego nowego wątku tworzonego przez aplikację wykorzystującą API należy zawołać funkcję AttachThreadToClarion z parametrem 1."

AF
  • Rejestracja:prawie 18 lat
  • Ostatnio:23 dni
1

No to za bardzo nie da się pomóc, jak nie podasz konkretów.

  1. Przede wszystkim podaj linki do biblioteki, bo googlowanie "nuget ClaRUN" niewiele mi dało.
  2. Umiesz to odtworzyć na jakimś małym kodzie?
  3. Masz zrzuty pamięci? Jak tak, to załącz je tutaj, wraz z symbolami. Tylko miej na uwadze, że wtedy da się podejrzeć cały kod Twojej aplikacji, więc jak masz tam coś poufnego, to nie załączaj nic, tylko odtwórz to w osobnej aplikacji.
BY
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 miesiące
  • Postów:39
0

To jest biblioteka dołączona do CDNXL więc na nuget jej nie ma. Niestety nie mogę odtworzyć tego błędu na mniejszym kodzie, ponieważ tak jak wcześniej już pisałem nie wiem jak ten błąd wywołać. Mam podejrzenia, ale je wykorzystując nie doSZEDŁem do tego błędu. Wiem tylko tyle, że wywala w nocy, ale też nie zawsze, mam założone logi. Z dokumentacji nic nie wynika, ponieważ tam są dosłownie 2 zdania, z czego jedno tu załączyłem. Drugie mówi to: "Aby w systemie Comarch ERP XL (platforma programistyczna Clarion 8) podpiąć API do wątku clarionowego, należy zaprototypować funkcję AttachThreadToClarion z biblioteki ClaRUN.DLL"

Damian Korczowski
Comarch mówi że ich API jest jednowątkowe. Sam miałem problem pisząc aplikację na IIS z wielowątkowością, ludzie rozwiązują to przez serwis WCF lub REST API. Z tego co widzę to prawdopodobnie wiesz o tym ale dla pewności zostawiam info ;-)
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)