C# - Как изменить элемент управления WinForms из асинхронного события

Рейтинг: 0Ответов: 1Опубликовано: 18.05.2023

Пытаюсь написать телеграм-бота не в консольном приложении, а в Window Forms. И столкнулся с проблемой. Я хочу, чтобы различные действия бота отображались в форме, если конкретно, то в RichTextBox. Но не получается это сделать, так действия происходят в статическом асинхронном методе. Как правильно поступить в этой ситуации? Прошу сильно не пинать - я начинающий и многого не знаю.

namespace TelegramBotTest
{
    public partial class Form1 : Form
    {
        private static ITelegramBotClient bot = new TelegramBotClient("TOKEN");

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var cts = new CancellationTokenSource();
            var cancellationToken = cts.Token;
            var receiverOptions = new ReceiverOptions
            {
                AllowedUpdates = { }, // receive all update types
            };
            bot.StartReceiving(
                HandleUpdateAsync,
                HandleErrorAsync,
                receiverOptions,
                cancellationToken
            );
            WriteToRichBox(DateTime.Now + ": запущен бот " + bot.GetMeAsync().Result.FirstName);
        }

        private static void WriteToRichBox(string s)
        {
            richTextBox.AppendText(s + "\n"); //Здесь ошибка "Для нестатического поля, метода или свойства требуется ссылка на объект"
        }

        public static async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
        {
            string st = Newtonsoft.Json.JsonConvert.SerializeObject(update);
            WriteToRichBox(st));
            if (update.Type == Telegram.Bot.Types.Enums.UpdateType.Message)
            {
                // Некоторые действия
            }
        }

        public static async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
        {
            // Некоторые действия
            WriteToRichBox(Newtonsoft.Json.JsonConvert.SerializeObject(exception));
        }
    }
}

Ответы

▲ 0Принят

Для записи не главного потока вы можете написать метод который будет писать в richTextBox. То есть выходим из потока и делаем запись в GUI

 public void Logger(string text)
        {
            richTextBox.Invoke((MethodInvoker)delegate
            {
                if (WriteToRichBox.Lines.Count() == 0)
                {
                    richTextBox.AppendText($"{text}");
                }
                else
                    richTextBox.AppendText($"\r\n{text}");
            });
        }

действия происходят в статическом асинхронном методе. Я бы удалил все статические методы и объекты. Так как в многопотоке если вы не обрабатываете, не блокируете данные для редактирования, в данных будет полная каша. Например в записи от 0 до 9 вы можете получить запись 0,1,2,2,2,2,2,2,2 и т.п