Хотя я согласен в целом с Jon тарелочкам, была интересная презентация Мадс Torgensen демонстрирует, как async/await
может быть используется для упрощения таких сценариев (с использованием методов, упомянутых Jon). В конце концов, это не то же самое, что с перечисляющими - мы можем написать собственный класс перечислителя, используя состояние, подобное индексу и т. Д., Но мы почти никогда этого не делаем и вместо этого используем блоки итераторов.
Во всяком случае, это техника async/await
, о которой мы говорили.
Во-первых, многоразовый часть:
public static class Utils
{
public static Task WhenClicked(this Button button)
{
var tcs = new TaskCompletionSource<object>();
EventHandler onClick = null;
onClick = (sender, e) =>
{
button.Click -= onClick;
tcs.TrySetResult(null);
};
button.Click += onClick;
return tcs.Task;
}
}
и ваш код, используя его (обратите внимание, что вам нужно, чтобы отметить свой метод как async
)
foreach (string s in List)
{
txtName.Text = s;
await yourButton.WhenClicked();
}
испытание образца положить все это вместе:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Samples
{
static class Test
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var txtName = new TextBox { Parent = form, Top = 8, Left = 8 };
var buttonNext = new Button { Parent = form, Top = txtName.Bottom + 8, Left = 8, Text = "Next" };
form.Load += async (sender, e) =>
{
var List = new List<string> { "A", "B", "C", "D " };
foreach (string s in List)
{
txtName.Text = s;
await buttonNext.WhenClicked();
}
txtName.Text = "";
buttonNext.Enabled = false;
};
Application.Run(form);
}
}
public static class Utils
{
public static Task WhenClicked(this Button button)
{
var tcs = new TaskCompletionSource<object>();
EventHandler onClick = null;
onClick = (sender, e) =>
{
button.Click -= onClick;
tcs.TrySetResult(null);
};
button.Click += onClick;
return tcs.Task;
}
}
}
Может быть состояние гонки, которое приводит к потерянным нажатием кнопки. Риск состоит в том, что есть щелчок между удалением события и добавлением нового события. Это будет зависеть от того, как имплантация ожидания взаимодействует с очередью сообщений Windows. –
@IanRingrose Согласен. Но это может не быть проблемой для такой программы, как симуляция типа обработки консоли, например, задание вопроса и ожидание ответа. –