以前、非同期で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 にはちゃんと"[テーブル名]"の形でテーブル名を指定したほうが吉。[]で囲ってないとやられる場合がある故。