Имеется необходимость на всём протяжении работы программы в некотором классе Watcher получать сообщения из некоего динамического буфера (Mailslot, для которого сделана обертка и имеется метод string Mailslot.GetMessage()). Класс Watcher создается при старте приложения, имеющего GUI, и, собственно, служит для наблюдения за содержимым Mailslot.
Разумеется, вариант с таким подходом работает:
bool DoListen = true;
while (DoListen)
{
var msg = Watcher.Instance().MailSlotServer.GetNextMessage();
if (msg != null)
{
listBox1.Items.Insert(0, msg);
}
Application.DoEvents();
}
Но такой подход не видится мне правильным. По идее, цикл опроса буфера нужно вынести в отдельный поток, или использовать BackgroundWorker, но подумалось мне, что данный момент можно было бы оформить и при помощи async/await. Но это не особо получается пока:
В классе Watcher создаю метод:
private async Task<string> GetMessage()
{
return await Task.Run(() => { var s = mailSlotServer.GetNextMessage(); return s; });
}
И там же реализую цикл:
public async void StartListen(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
string s = await GetMessage();
if (!string.IsNullOrEmpty(s))
(FormMain.ActiveForm as FormMain).listBox1.Items.Insert(0, s);
await Task.Delay(100);
}
}
Теперь при старте приложения пытаюсь вызвать цикл прослушивания, для теста пока вызываю из обработчика события Load:
...
var ct = new CancellationToken();
Watcher.Instance().StartListen(ct);
...
VS вываливается с ArgumentNullException при попытке вставки строки в listBox1.
Полагаю, что на момент попытки вставки s переменная, полученная через await GetMessage() действительно пустая.
Вот и возникает вопрос, как правильнее реализовать такой механизм?
UPDATE
Всё заработало именно в указанном виде, а ошибка возникала из-за использования ActiveForm, который становится null как только форма перестает быть активной (спасибо Pavel Mayorov!)
Если отказаться от использования ActiveForm, то всё работает. listBox(или другой GUI-контрол) можно передавать внутрь метода StartListen по ссылке, или не использовать тут GUI вовсе (что и было сделано автором вопроса).
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости