以前、非同期でBulkCopyするのを書いた。それのちょっと追記版。
MSDN見てたら「WriteToServerAsync」っていうのがあった。っていうか普通に非同期用のメソッドあるんじゃん・・・。とゆーことでこっちを使って書き直す。
//using System; //using System.Data; //using System.Data.SqlClient; string ConnectionString = @"****"; DataTable templateDt = new DataTable();//BulkCopy用のDataTable定義テンプレ public void sample() { /*サンプルテーブル create table HogeTable( intval int, str1 varchar(100), str2 varchar(100), str3 varchar(100), str4 varchar(100), ) */ //最初にDataTableの定義を作るのメンドーなので対象テーブルを空SELECTしてSqlDataReaderから定義を作る using (SqlConnection cn_ = new SqlConnection(ConnectionString)) { cn_.Open(); SqlCommand command = new SqlCommand(); command.CommandText = "select top 0 * from [HogeTable]"; command.Connection = cn_; using (SqlDataReader sqlDr = command.ExecuteReader()) { DataTable schemaDt = sqlDr.GetSchemaTable(); foreach (DataRow schemaDr in schemaDt.Rows) { string columnName = schemaDr["ColumnName"].ToString().Trim(); string dataType = schemaDr["DataType"].ToString().Trim(); DataColumn dc = new DataColumn(); dc.ColumnName = columnName; dc.DataType = System.Type.GetType(dataType); templateDt.Columns.Add(dc); } } } Console.WriteLine("同期実行====="); Console.WriteLine("Start:{0}", DateTime.Now); for (int i = 0; i < 3; i++)//3回やる { DataTable copyFromDataTable = CreateTestData(500000);//50万件のテストデータ using (SqlConnection cn_ = new SqlConnection(ConnectionString)) { cn_.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn_)) { bulkCopy.DestinationTableName = String.Format("dbo.[{0}]", "HogeTable"); try { bulkCopy.WriteToServer(copyFromDataTable); } catch (Exception e) { Console.WriteLine(e.Message); } } } Console.Write("*");//進捗的な } Console.WriteLine(""); Console.WriteLine("End:{0}", DateTime.Now); Console.WriteLine("非同期実行====="); st = DateTime.Now; Console.WriteLine("Start:{0}", DateTime.Now); for (int i = 0; i < 3; i++)//3回やる { DataTable copyFromDataTable = CreateTestData(500000);//50万件のテストデータ AsyncSqlBulkCopy(copyFromDataTable, String.Format("dbo.[{0}]", "HogeTable")); Console.Write("*");//進捗的な } Console.WriteLine(""); ed = DateTime.Now; Console.WriteLine("End:{0}", DateTime.Now); } //非同期実行用 public async void AsyncSqlBulkCopy(DataTable bulkFrom,string distTableName) { using (SqlConnection conn = new SqlConnection(ConnectionString)) { await conn.OpenAsync(); using (SqlBulkCopy bcp = new SqlBulkCopy(conn)) { bcp.DestinationTableName = distTableName; await bcp.WriteToServerAsync(bulkFrom); } } } //テストデータ作る public DataTable CreateTestData(int count) { DataTable copyFromDataTable = templateDt.Clone(); string kyedatetime = DateTime.Now.ToString("yyyyMMddHHmmssfff"); for (int i = 0; i < count; i++) { var addRow = copyFromDataTable.NewRow(); addRow.BeginEdit(); addRow[0] = i; addRow[1] = String.Format("str1_{0}", kyedatetime); addRow[2] = String.Format("str2_{0}", kyedatetime); addRow[3] = String.Format("str3_{0}", kyedatetime); addRow[4] = String.Format("str4_{0}", kyedatetime); addRow.EndEdit(); copyFromDataTable.Rows.Add(addRow); } return copyFromDataTable; }
非同期の方が同期実行時の半分くらいの時間だった。まぁデータが登録終わるまでの時間は変わんないけどネ。。。
ちなみにDestinationTableName にはちゃんと"[テーブル名]"の形でテーブル名を指定したほうが吉。[]で囲ってないとやられる場合がある故。