雖然我一般同意喬恩斯基特,有通過的Mads 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;
}
}
}
可能存在導致丟失按鈕點擊的競態條件。風險在於刪除事件和添加新事件之間有點擊。這將取決於await的植入如何與windows消息隊列交互。 –
@IanRingrose同意。但是,對於像這樣的程序來說,這可能不是問題 - 模擬控制檯類型的處理,如詢問問題並等待響應。 –