
Вывод правда я сделал в Label, а не TextBox, ну да это по невнимательности.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//источник токена отмены
private CancellationTokenSource _tokenSource;
private async void buttonStart_Click(object sender, EventArgs e)
{
//через него будем оповещать о ходе выполнения задачи
Progress<string> progess = new Progress<string>(text => this.labelOutput.Text = text);
//готовим токен отмены
_tokenSource = new CancellationTokenSource();
CancellationToken cancelToken = _tokenSource.Token;
//кнопки
buttonStart.Enabled = false;
buttonCancel.Enabled = true;
try
{
await Task.Run(() => DoIteration(cancelToken, progess), cancelToken);
}
catch (OperationCanceledException)
{
//случай отмены
this.labelOutput.Text = "0";
}
catch (Exception)
{
this.labelOutput.Text = "Ошибка";
}
finally
{
//кнопки
buttonStart.Enabled = true;
buttonCancel.Enabled = false;
}
}
//метод выводит числа
private void DoIteration(CancellationToken cancelToken, IProgress<string> progess)
{
Iteration iteration = new Iteration();
foreach (int number in iteration.StartIterator())
{
progess.Report(number.ToString());
//выбрасываем исключение в случае нажатия на кнопку отмены
cancelToken.ThrowIfCancellationRequested();
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
_tokenSource.Cancel();
}
}
class Iteration
{
public IEnumerable<int> StartIterator()
{
for (int i = 0; i < 1000; i++)
{
// Вывод числа i.
Thread.Sleep(100);
yield return i;
}
}
}
StartIterator()возвращал неvoid, аIEnumerable<int>для этого нужно будет в цикле использоватьyield return i. – Bulson Dec 24 '17 at 13:52