1

Есть метод, который выполняется асинхронно:

public static Task<LogDB> ReadAsync()
    {
        var quene = new ConcurrentQueue<byte[]>();

        return Task<LogDB>.Factory.StartNew(() =>
        {
            var read = Task.Factory.StartNew(() =>
            {
                GetState(out uint journalSize,
                    out uint freeMemAddr,
                    out uint eventRecordNo);
                //дальше выполняем только если количество событий больше 0
                if (eventRecordNo > 0)
                {
                    //текущая страница
                    var currentPage = freeMemAddr;
                    //количество страниц
                    var countPage = journalSize / LOG_PAGE_length;
                    //количество уже прочтенных страниц
                    var addedPage = 0;
                    //для проверки добавленных страниц
                    var numPage = true;
                    //для проверки страниц на пустоту
                    var empty = true;

                    while (numPage && empty)
                    {
                        //определяем адрес страницы
                        if (currentPage == 0)
                            currentPage = journalSize;
                        currentPage = (--currentPage) & 0xFFFFFF00;
                        //собираем запрос
                        var instr = GetPageInstr(currentPage);
                        //получаем страницу
                        var answer = UploadingData.LoadData(instr, 250);
                        //проверяем ответ
                        if (answer != null
                            && answer.Length == GET_PAGE_ANSWER_length
                            && CRC16.Check(answer)
                            && answer[0] == SLAVEID
                            && answer[1] == GET_PAGE_COMMAND)
                        {
                            //проверяем на пустоту
                            if (CheckEmpty(answer.Range(6, 261)))
                            {
                                //добавляем в очередь
                                quene.Enqueue(answer);
                                //увеличиваем количество добавленных
                                addedPage++;
                                //сравниваем количество добавленных
                                if (addedPage >= countPage)
                                    numPage = false;
                            }
                            else
                                empty = false;
                        }
                    }

                }
            });
            read.Wait();
            var logDB = new LogDB();
            while(!quene.IsEmpty)
            {
                if(quene.TryDequeue(out byte[] rawData)
                    && rawData.Length == GET_PAGE_ANSWER_length
                    && CRC16.Check(rawData)
                    && rawData[0] == SLAVEID)
                {
                    logDB.AddLogPage(rawData);
                }
            }
            return logDB;
        });
    }

Одна задача должна читать данные из системы, а вторая добавлять их в БД. Как это реализовать? Пробовал убрать read.Wait(); и в условие цикла во второй задаче проверять статус выполнения первой задачи, но это не помогло.

andreycha
  • 25,167
  • 4
  • 46
  • 82
  • 1
    Возможный дубликат: https://ru.stackoverflow.com/q/428327/218063 – Андрей NOP Jun 12 '18 at 12:41
  • @АндрейNOP, неужели для реализации такой задачи нужно использовать потоки? И столько переписывать? – UporotayaPanda Jun 12 '18 at 12:49
  • Можете использовать Task вместо Thread, но реализацию возьмите оттуда. – Андрей NOP Jun 12 '18 at 12:51
  • @АндрейNOP, а можете помочь с реализацие? Без внутреннего функционала, зачем использовать блокинг? Ведь ConcurrentQueue потока безопасна... – UporotayaPanda Jun 12 '18 at 13:00
  • Почитайте Албахари, BlockingCollection блокирует поток если очередь пустая, при использовании ConcurrentXXX поток будет бесцельно жрать процессорное время – Андрей NOP Jun 12 '18 at 13:27
  • @АндрейNOP а если в 'BlockingCollection' количество элементов достигло, например ограничения в 10 итемов, и задача пытается добавить еще итем, она замрет, пока ей это не удастся? – UporotayaPanda Jun 12 '18 at 14:33
  • Да, будет ожидать пока "место освободится". Но если вам это не нужно – ограничение можно не включать – Андрей NOP Jun 12 '18 at 15:39
  • @АндрейNOP на основе вашей ссылки и совета про BlockingCollection я написал свой алгоритм) Спасибо вам) а как отметить? – UporotayaPanda Jun 18 '18 at 15:54

0 Answers0