Parallel.ForeachおよびBulkCopy

parallel-foreach sqlbulkcopy

質問

私は同じデータベース構造の59のサーバに接続し、同じテーブルに私のローカルDBにデータをインポートするC#ライブラリを持っています。現時点では、foreachループでサーバーごとにデータサーバーを取得しています。

foreach (var systemDto in systems)
{
    var sourceConnectionString = _systemService.GetConnectionStringAsync(systemDto.Ip).Result;
    var dbConnectionFactory = new DbConnectionFactory(sourceConnectionString,
        "System.Data.SqlClient");
    var dbContext = new DbContext(dbConnectionFactory);
    var storageRepository = new StorageRepository(dbContext);
    var usedStorage = storageRepository.GetUsedStorageForCurrentMonth();

    var dtUsedStorage = new DataTable();
    dtUsedStorage.Load(usedStorage);
    var dcIp = new DataColumn("IP", typeof(string)) {DefaultValue = systemDto.Ip};
    var dcBatchDateTime = new DataColumn("BatchDateTime", typeof(string))
    {
        DefaultValue = batchDateTime
    };
    dtUsedStorage.Columns.Add(dcIp);
    dtUsedStorage.Columns.Add(dcBatchDateTime);

    using (var blkCopy = new SqlBulkCopy(destinationConnectionString))
    {
        blkCopy.DestinationTableName = "dbo.tbl";
        blkCopy.WriteToServer(dtUsedStorage);
    }
}

データを取得するシステムはたくさんあるので、Pararel.Foreachループを使用することが可能かどうか疑問に思いますか? BulkCopyはWriteToServer中にテーブルをロックし、次のWriteToServerは前回の完了まで待機しますか?

- EDIT 1

ForeachをParallelに変更しました.Foreachが問題に直面しています。このループの中に私は非同期メソッドを持っています:_systemService.GetConnectionStringAsync(systemDto.Ip)とこの行はエラーを返します:

System.NotSupportedException:以前の非同期操作が完了する前に、このコンテキストで開始された2番目の操作。このコンテキストで別のメソッドを呼び出す前に、非同期操作が完了したことを確認するには、 'await'を使用します。どのインスタンスメンバーもスレッドセーフであるとは限りません。

任意のアイデアはどのように私はこれを処理できますか?

エキスパート回答

通常はブロックされ、前の操作が完了するまで待機します。

SqlBulkCopyを並列で実行するかどうかに影響を及ぼす要因がいくつかあります。

.NETバルク・オペレーションParallel機能を追加する際には、 Parallel正しく動作させるのに苦労しましたが、テーブルにインデックスがない場合(正常に動作しない可能性があります)

作業しても、パフォーマンスの向上はそれほど速くはありませんでした。

MSDN - テーブルレベルのロックと並行してデータをインポートする



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ