Как асинхронно выводить текст в TextBox C#?
Есть самописанный класс, в котором метод выполняющий действия с задержками с помощью Thread.Sleep(), и есть форма с TextBox, в который после выполнения метода должен поместиться текст, но вызывается этот метод несколько раз и мне нужно, чтобы после каждого выполнения метода текст обновлялся, а он обновляется только после выполнения всех вызовов метода из самописанного класса. Я пытался вызывать эти методы ассинхронно, тогда все работало, но все слипалось потому что Thread.Sleep перестал работать.
Ответы (2 шт):
Автор решения: augustfu
→ Ссылка
Помог банальный вызов Refresh() из класса Control после завершения работы одной иттерации метода
Автор решения: Frehzy
→ Ссылка
Ужасный способ. Прошу, не делайте так никогда. Используйте привязки:
public partial class Form1 : Form, INotifyPropertyChanged
{
private Random _rnd; //поле для создания рандомного значения. Вам оно не нужно. Существует только для тестов
private decimal _fieldForTextBox; //поле, которое хранит информацию
public decimal FieldForTextBox //свойство, которое мы должны обновлять
{
get => _fieldForTextBox;
set
{
_fieldForTextBox = value;
OnPropertyChanged(nameof(FieldForTextBox));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public Form1()
{
InitializeComponent();
_rnd = new Random();
//ниже привязка textBox к свойству FieldForTextBox
textBox1.DataBindings.Add(nameof(TextBox.Text), this, nameof(FieldForTextBox), false, DataSourceUpdateMode.OnPropertyChanged);
}
public async Task Start()
{
//какой-то метод, который просто запускает задачу на расчёт чего-то
FieldForTextBox = await Divide(_rnd.Next(0, 50), _rnd.Next(0, 50));
await Task.Delay(TimeSpan.FromSeconds(2));
FieldForTextBox = await Divide(_rnd.Next(0, 50), _rnd.Next(0, 50));
await Task.Delay(TimeSpan.FromSeconds(2));
FieldForTextBox = await Divide(_rnd.Next(0, 50), _rnd.Next(0, 50));
}
private async Task<decimal> Divide(int a, int b)
{
//какой-то метод, который ждёт чего-то и возвращает результат
return await Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(1));
return decimal.Divide(a, b);
});
}
private void Form1_Load(object sender, EventArgs e) =>
Start();
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}