Есть метод, который выполняется асинхронно:
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(); и в условие цикла во второй задаче проверять статус выполнения первой задачи, но это не помогло.
BlockingCollectionблокирует поток если очередь пустая, при использованииConcurrentXXXпоток будет бесцельно жрать процессорное время – Андрей NOP Jun 12 '18 at 13:27