问题
I have quite a few datatable to bulkinsert into databasetable Due to large size, one table took 5 min to complete insert. 2 tables took me 10 min
static void Main(string[] args)
{
DataTableBulkInsert(DataTable1);
DataTableBulkInsert(DataTable2);
}
public static void DataTableBulkInsert(DataTable Table){
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(myConnection);
sqlBulkCopy.DestinationTableName = "dbo.DatabaseTable";
myConnection.Open();
sqlBulkCopy.WriteToServer(Table);
myConnection.Close();
}
I am now trying to do a async for Bulk insert, but there is neither any data inserted nor giving me error. How to capture the exception?
static void Main(string[] args)
{
var insert1 = Task.Run(async () => await DataTableBulkInsert(DataTable1);
var insert2 = Task.Run(async () => await DataTableBulkInsert(DataTable2);
Task.WhenAll( insert1, insert 2);
}
public static async Task<Boolean> DataTableBulkInsert(DataTable Table)
{
try
{
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(myConnection);
sqlBulkCopy.DestinationTableName = "dbo.DatabaseTable";
myConnection.Open();
await sqlBulkCopy.WriteToServerAsync(Table);
myConnection.Close();
}
catch (Exception (e))
{
console.write(e);
}
return true;
}
回答1:
The Task.Run
s are adding nothing useful here. Also, don't try to share a single connection object between the two runs of your method. Something like:
static void Main(string[] args)
{
var insert1 = DataTableBulkInsert(DataTable1);
var insert2 = DataTableBulkInsert(DataTable2);
Task.WaitAll( insert1, insert2);
}
public static async Task DataTableBulkInsert(DataTable Table)
{
using(var localConnection = new SqlConnection(/* connection string */))
{
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(localConnection );
sqlBulkCopy.DestinationTableName = "dbo.DatabaseTable";
localConnection.Open();
await sqlBulkCopy.WriteToServerAsync(Table);
}
}
Normally return await
is an anti-pattern, but here you want to use it so that the using
statement doesn't close your connection until after the bulk load is complete.
Also, I switched to using Task.WaitAll which actually waits, which is more idiomatic than using Task.WhenAll
and then immediately calling Wait
on it.
回答2:
Task.WhenAll
returns a Task object that needs to be awaited or the code that follows continues its normal execution and the main method exits immediately.
Since this is a console application and the main can't be marked as async
, you can use this:
Task.WhenAll(insert1, insert2).Wait(); // wait for the returned Task object to Complete
The normal usage is: await (Task.WhenAll(...))
but you can't mark Main as an async
method.
来源:https://stackoverflow.com/questions/38759458/async-for-bulk-copy