异步进行大容量复制

本文关键字:复制 大容量 步进 异步 | 更新日期: 2023-09-27 18:00:58

我有很多数据表要扩充到数据库中由于其尺寸较大,一张桌子需要5分钟才能完成插入。两张桌子花了我10分钟

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

我现在正试图为Bulk插入做一个异步操作,但既没有插入任何数据,也没有给我错误。如何捕获异常?

static void Main(string[] args)
{
     var insert1 = Task.Run(async () => await DataTableBulkInsert(DataTable1);
     var insert2 = Task.Run(async () => await DataTableBulkInsert(DataTable2);
     Task.WhenAll( insert1, insert2);
}
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;
 }

异步进行大容量复制

Task.Run在这里没有添加任何有用的内容。此外,不要试图在方法的两次运行之间共享一个连接对象。类似于:

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

通常情况下,return await是一个反模式,但在这里您希望使用它,以便using语句在大容量加载完成之前不会关闭您的连接。

此外,我切换到使用Task.WaitAll,它实际上等待,这比使用Task.WhenAll然后立即调用它上的Wait更惯用。

Task.WhenAll返回一个需要等待的Task对象,或者后面的代码继续正常执行,主方法立即退出。

由于这是一个控制台应用程序,主应用程序不能标记为async,因此可以使用以下内容:

Task.WhenAll(insert1, insert2).Wait(); // wait for the returned Task object to Complete

通常的用法是:await (Task.WhenAll(...)),但不能将Main标记为async方法。