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);
}