我需要在foreach
循环完成搜索List<>
中的每个项目时触发回调。
private async void startSearchBtn_Click(object sender, EventArgs e)
{
await Search(files, selectTxcDirectory.SelectedPath, status);
}
private static async Task Search(List<string> files, string path, Label statusText)
{
foreach (string file in files)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(file);
statusText.Text = "Started scanning...";
using (XmlReader reader = XmlReader.Create(new StringReader(xmlDoc.InnerXml), new XmlReaderSettings() { Async = true }))
{
while (await reader.ReadAsync())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "LineName"))
{
Console.WriteLine(reader.ReadInnerXml());
}
}
}
}
}
这可能吗?如果可以的话怎么办呢?
答案 0 :(得分:18)
这很简单,只需将方法作为参数传递给参数。然后在任何需要的地方调用它。
private async void startSearchBtn_Click(object sender, EventArgs e)
{
await Search(files, selectTxcDirectory.SelectedPath, status, SearchCompleted); // <-- pass the callback method here
}
private static async Task Search(List<string> files, string path, Label statusText, Action<string> callback)
{
foreach (string file in files)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(file);
statusText.Text = "Started scanning...";
using (XmlReader reader = XmlReader.Create(new StringReader(xmlDoc.InnerXml), new XmlReaderSettings() { Async = true }))
{
while (await reader.ReadAsync())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "LineName"))
{
Console.WriteLine(reader.ReadInnerXml());
}
}
}
// Here you're done with the file so invoke the callback that's it.
callback(file); // pass which file is finished
}
}
private static void SearchCompleted(string file)
{
// This method will be called whenever a file is processed.
}
答案 1 :(得分:3)
我会在下面编写代码。这样,您仍然可以跟踪待处理任务(_pendingSearch
),同时startSearchBtn_Click
保持同步。
您应该跟踪待处理的任务(并且能够取消它们)。否则,用户可以连续两次单击startSearchBtn
并生成两个搜索任务。在您的情况下,这仍然可能是有效的情况,但通常不是。
Task _pendingSearch = null;
private void startSearchBtn_Click(object sender, EventArgs e)
{
// check if is _pendingSearch != null and still pending here
_pendingSearch = Search(files,
selectTxcDirectory.SelectedPath, status).ContinueWith((finishedTask) =>
{
// Place your completion callback code here
}, TaskScheduler.FromCurrentSynchronizationContext);
}
private static async Task Search(List<string> files, string path, Label statusText)
{
// ...
}
[已编辑] 使用await
:
Task _pendingSearch = null;
private async void startSearchBtn_Click(object sender, EventArgs e)
{
// check if is _pendingSearch != null and still pending here
_pendingSearch = Search(files, selectTxcDirectory.SelectedPath, status);
await _pendingSearch;
// Place your completion callback code here
}
答案 2 :(得分:1)
由于您使用的是await
,因此startSearchBtn_Click
中的代码在Search
完成之前不会继续。
你需要的就是这样:
private async void startSearchBtn_Click(object sender, EventArgs e)
{
await Search(files, selectTxcDirectory.SelectedPath, status);
// run your callback here
}