C# 5 / .NET 4.5 中的 async-awqait 模式与此完美匹配。我看到您已将其标记为 .NET4,但如果您可以使用Async Targeting Pack,则有一种非常优雅的方法:
void Main()
{
foreach (string file in Directory.EnumerateFiles(folderPath, "*.xml"))
{
currentReader = new XmlDataReader(transferInstructions, file); //load file
currentReader.RowsUploaded += new EventHandler<RowsUploadedEventArgs>(currentReader_RowsUploaded);
currentReader.TableUploaded += new EventHandler<TableUploadedEventArgs>(currentReader_TableUploaded);
var task = Task.Factory.StartNew(() => currentReader.executeBulkCopy(initialConnString, workingDatabase));
await task;
cleanUp(task);
MessageBox.Show("Complete!");
writeResult("Started the transfer process.");
cmdDataTransfer.Text = "CANCEL TRANSFER";
cmdDataTransfer.ForeColor = Color.DarkRed;
transferAction = () => cancelCurrentReader();
}
}
如果您必须保留它 VS2010,则必须模仿 async-await 的功能,类似于:
void MyForm()
{
_syncContext = SynchronizationContext.Current;
Execute(Directory.EnumerateFiles(folderPath, "*.xml").GetEnumerator());
}
void Execute(IEnumerator<string> files)
{
if (!files.MoveNext())
{
files.Dispose();
return;
}
Task.Factory.StartNew(() => Execute(files.Current)).ContinueWith(() => Execute(files));
}
public void Execute(string file)
{
currentReader = new XmlDataReader(transferInstructions, file); //load file
currentReader.RowsUploaded += new EventHandler<RowsUploadedEventArgs>(currentReader_RowsUploaded);
currentReader.TableUploaded += new EventHandler<TableUploadedEventArgs>(currentReader_TableUploaded);
() => currentReader.executeBulkCopy(initialConnString, workingDatabase);
cleanUp(task);
_syncContext.Send(updateGUI);
transferAction = () => cancelCurrentReader();
}
public void updateGUI()
{
MessageBox.Show("Complete!");
writeResult("Started the transfer process.");
cmdDataTransfer.Text = "CANCEL TRANSFER";
cmdDataTransfer.ForeColor = Color.DarkRed;
}
编辑现在我想到它还有一种更简单的方法。您可以让整个循环在它自己的任务中运行(委派给同步上下文以进行 GUI 工作)。使用上面代码的约定:
Task.Factory.StartNew(() =>
{
foreach (var file in Directory.EnumerateFiles(folderPath, "*.xml"))
Execute(file);
}