У меня следующая логика:
public void InQueueTable(DataTable Table)
{
int incomingRows = Table.Rows.Count;
if (incomingRows >= RowsThreshold)
{
// asyncWriteRows(Table)
return;
}
if ((RowsInMemory + incomingRows) >= RowsThreshold)
{
// copy and clear internal table
// asyncWriteRows(copyTable)
}
internalTable.Merge(Table);
}
Существует одна проблема с этим лагоритом:
Дано RowsThreshold = 10000
Если incomingRows
ставит RowsInMemory
свыше RowsThreshold
: (1)
асинхронно записывать данные, (2)
объединить входящие данные
Если incomingRows
больше
RowsThreshold
, асинхронная запись
входящие данные
Но что, если ??? Предположим, что второй поток раскручивается и вызывает asyncWriteRows (xxxTable); также, что каждый поток, владеющий асинхронным методом, будет писать в одну и ту же таблицу в SqlServer: Обрабатывает ли SqlServer этот вид многопоточной функциональности записи в одну и ту же таблицу?
Последующие действия
По предложению Грега Д.:
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString,
sqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.UseInternalTransaction))
{
// perform bulkcopy
}
Несмотря на это, у меня все еще есть проблема сигнализации asyncWriteRows (copyTable). Алгоритм должен определить необходимость идти вперед и скопировать internalTable, clear internalTable и asyncWriteRows (copyTable). Я думаю, что мне нужно перевести вызов internalTable.Copy()
на собственный метод:
private DataTable CopyTable (DataTable srcTable)
{
lock (key)
{
return srcTable.Copy();
}
}
... а затем следующие изменения в методе InQueue:
public void InQueueTable(DataTable Table)
{
int incomingRows = Table.Rows.Count;
if (incomingRows >= RowsThreshold)
{
// asyncWriteRows(Table)
return;
}
if ((RowsInMemory + incomingRows) >= RowsThreshold)
{
// copy and clear internal table
// asyncWriteRows(CopyTable(Table))
}
internalTable.Merge(Table);
}
... наконец, добавьте метод обратного вызова:
private void WriteCallback(Object iaSyncResult)
{
int rowCount = (int)iaSyncResult.AsyncState;
if (RowsInMemory >= rowCount)
{
asyncWriteRows(CopyTable(internalTable));
}
}
Это то, что я определил как решение. Есть отзывы?