• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Przerywanie Task c#

Object Storage Arubacloud
0 głosów
710 wizyt
pytanie zadane 27 maja 2017 w C# przez jankustosz1 Nałogowiec (35,880 p.)
private BinaryReader br;
private TcpClient client
        public void Connect()
        {
            client = new TcpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1313));
            br = new BinaryReader(client.GetStream());

        }
        private Task taskReceive;
        public object lockDane = new object();
        public List<string> dane = new List<string>();
        public void BeginReceive()
        {
            taskReceive = Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    string str = br.ReadString();
                    lock (lockDane)
                        dane.Add(str);
                }
            });
        }
        public void EndReceive()
        {
            taskReceive.Abort(); // nie ma takiej metody w task
        }

Witam. Mam mniej więcej taki problem. Nie mam pojęcia jak zaimplementować metodę EndReceive, aby działała dobrze. W thread używałem metody abort ale w task jej nie ma. Także i takie coś https://stackoverflow.com/questions/4783865/how-do-i-abort-cancel-tpl-tasks jest dla mnie złe bo odbieranie blokuje wątek i może trwać nawet kilka minut, a ja chcę aby EndReceive zadziałało natychmiast. Jak sobie z tym poradzić?

2 odpowiedzi

0 głosów
odpowiedź 30 maja 2017 przez daniell89 Nowicjusz (240 p.)
private CancellationTokenSource source = new CancellationTokenSource();
        private CancellationToken token;

        public void Connect()
        {
            client = new TcpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1313));
            br = new BinaryReader(client.GetStream());
        }
        
        public async void BeginReceive()
        {           
            token = source.Token;
            await Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    if (source.IsCancellationRequested)
                        return;

                    string str = br.ReadString();
                    lock (lockDane)
                        dane.Add(str);
                }
            },
            token);
        }
        public void EndReceive()
        {
            source.Cancel();
        }

Możesz spróbować takiego rozwiązania.

Co prawda Task'a nie można zakończyć metodą Abort (jak w przypadku klasy Thread), ale wykorzystując async/await z poziomu interfejsu użytkownika nie będzie widoczne, że po kliknięciu np. "zakończ" program dokończy w tle aktualny odczyt (ale go nie zapisze bo sprawdzi wcześniej właściwość "IsCancellationRequested").

komentarz 30 maja 2017 przez jankustosz1 Nałogowiec (35,880 p.)
Właśnie widziałem takie rozwiązanie ale ono jest złe co jakby np. 2 strona wysyłała dane raz na 10 minut?

Wtedy jakby się chciało wywołać EndReceive to co 10 minut się będzie czekać aż wykona się metoda ReadString() ? W thread metoda abort zrobiłaby to natychmiastowo.
–1 głos
odpowiedź 29 maja 2017 przez Bartłomiej Łaski Mądrala (5,100 p.)
edycja 29 maja 2017 przez Bartłomiej Łaski

Łooo panie, a słyszał pan o czym takim jak funkcje async ?

        public async void EndReceive()
        {
            await taskReceive.Abort(); TADAM, zostanie to wywołane od oddzielnym wątku :)
        }

        public async Task EndReceive()
        {
            await taskReceive.Abort(); TADAM, zostanie to wywołane od oddzielnym wątku :)
            return cos // jak chcesz cos zwrocic po skoczeniu await.
        }


Tak samo robie coś takiego jak Task.Run(COS TAM).Result, odpali Ci to w tym samym wątku.

komentarz 29 maja 2017 przez jankustosz1 Nałogowiec (35,880 p.)
Nijak się ma to co napisałeś do mojego problemu a w dodatku twój kod się nie skompiluje bo jak już wcześniej napisałem task nie zawiera metody abort.

Ponadto async i await nie ma w .net framework 4.0
komentarz 29 maja 2017 przez Bartłomiej Łaski Mądrala (5,100 p.)
Dobra tylko gdzie napisałeś ze używasz .NET 4.0?
Tak samo sam używasz objectu Task, w kodzie który podałeś, więc męcz się dalej pozdrawiam :)
komentarz 29 maja 2017 przez jankustosz1 Nałogowiec (35,880 p.)
To że nie ma w 4.0 to taki szczegół który napisałem. Chodzi o to że async jest mi potrzebne w tym problemie jak dziura w moście bo nie rozwiązuje mojego problemu a mianowicie jak przerwać task.
komentarz 29 maja 2017 przez Bartłomiej Łaski Mądrala (5,100 p.)

Tutaj w 3 odpowiedzi masz jak podac do Task`a Token, ktory go bedzie mogl anulować. 
Nazywa sie to CancellationToken

komentarz 30 maja 2017 przez JAKUBW Nałogowiec (33,470 p.)
Asynchroniczne metody wykonują się w tym samym wątku.
komentarz 30 maja 2017 przez jankustosz1 Nałogowiec (35,880 p.)
Napisałem komentarz pod Daniell89. Cały problem tkwi w tym że muszę w pętli wywoływać coś takiego: cancelToken.ThrowIfCancellationRequested();

A jakby odbieranie danych trwało dłużej to EndReceive działałoby ze zbyt dużym opóźnieniem.

Podobne pytania

0 głosów
0 odpowiedzi 119 wizyt
pytanie zadane 26 listopada 2018 w C# przez kubekszklany Gaduła (3,190 p.)
+1 głos
2 odpowiedzi 342 wizyt
pytanie zadane 10 marca 2020 w C# przez JakSky Stary wyjadacz (14,770 p.)
+1 głos
1 odpowiedź 1,357 wizyt
pytanie zadane 18 kwietnia 2015 w C# przez Dorion300 Szeryf (90,250 p.)

92,555 zapytań

141,403 odpowiedzi

319,556 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...