Zakończenie metody po określonym timeoucie i zwrócenie wyniku

0

Witam,

Mam pewnien problem programowaniem asynchronicznym w C#. Mam zdanaie wykonujące się w pętli i pobierające za każdym jej przebiegiem jedną wiadomość. Wiadomości są zapisywane na liście. Metoda pobierająca powinna działać tak że pobiera wiadomości dopóki : nie osiągnie max ilości wiadomości lub gdy timeout nie zostanie osiągnięty. W obu przypadkach powina zostać zwrócona zawartość listy (albo z max ilością wiadomości albo lista pusta). Potrzebuję jakiegos naprowadzenia bo przez ostatnie 2 dni wyorzystaęłm już wszytskie chyba mozliwości użycia caneclationToken. Jakieś wtępne pomysły ? Aha nie ma opcji po prostu puszczenia while tak żeby wykorzystywal 100% CPU.

0

Aha nie ma opcji po prostu puszczenia while tak żeby wykorzystywal 100% CPU. ?

I podaj jakiś przykładowy kod to będzie prościej.

0

Nie wiem czy dobrze myślę, ale tak schematycznie to może by (mniej więcej !) coś takiego zadziałało:

  private List<object> GetMessages(int timeout,int max)
        {
            List<object> messages = new List<object>();
            object msg;
            int count = 0;
            DateTime start = DateTime.Now;
            while ((DateTime.Now - start).TotalMilliseconds < timeout && count < max)
            {
                msg = GetSomeMessageObject();
                if (msg == null)
                    Thread.Sleep(20); // czekanie na wiadomość bo ostatnia była null czy coś ...
                else ++count;
            }
            return messages;
        }
0

Kod który ma i który nie do końca działa. Szukam czegos lepszego

   private IEnumerable<ITextMessage> FetchMessagesWorker(IMessageConsumer consumer, CancellationToken token)
        {
            List<ITextMessage> messages = new List<ITextMessage>();
            bool previousStepFetchedMessage = false;
            _logger.Debug("Before condition");
            do
            {
                var message = previousStepFetchedMessage ? consumer.ReceiveNoWait() : consumer.Receive();
                if (message != null)
                {
                    messages.Add(message as ITextMessage);
                    previousStepFetchedMessage = true;
                }
                else
                {
                    previousStepFetchedMessage = false;
                }
            } while (!token.IsCancellationRequested);
            return messages;
        }

        private IEnumerable<ITextMessage> FetchBatch(IMessageConsumer consummer)
        {
            _cancellationTokenSource=new CancellationTokenSource();
            _cancellationTokenSource.CancelAfter(TimeSpan.FromMilliseconds(1000));
            return Task.Factory.StartNew(
                (source) => FetchMessagesWorker(consummer, ((CancellationTokenSource) source).Token),
                _cancellationTokenSource).Result;

        } 
0

Może override z timespan zadziala http://activemq.apache.org/nms[...]pache_NMS_IMessageConsumer.htm http://activemq.apache.org/nms[...]_Receive%60%601_2_712bf428.htm
Jeśli będziesz skracał w każdym obrocie pętli czas oczekiwania, na podstawie DateTime.Now to z dokładnością +/- 16ms uzyskasz co chcesz :)

0

Ok. Poradziłęm sobie z tym w inny sposób. Czesm jednak odejście na chwilę od kompa pomaga. Niestety sposób jest specyficzny dla ActiveMQ więc nie wiem czy jego publikacja coś komuś na przyszłość pomoże.

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