Используя С#, я хочу генерировать 1,000,000 файлов из БД, каждая запись в отдельном файле. Каков наилучший способ сгенерировать эти файлы за минимальное время?
Вот мой код без потоковой передачи:
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); // to calculate the execution time in case of using threading
SqlCommand cmd = new SqlCommand(@"select top 1000000 p1+','+p2+','+p3+','+p4 as line from lines ", con);
con.Open();
var rdr = cmd.ExecuteReader();
int i = 0;
while (rdr.Read())
{
string line = rdr.Getring(0);
string filename = String.Format("file{0}.txt", ++i);
File.WriteAllText(filename, line);
}
rdr.Close();
con.Close();
Поскольку ваши операции привязаны к IO, а не к ЦП, лучший способ - иметь 2 потока, один из которых считывает из БД записи и помещает их в очередь, а другой читает из очереди и генерирует файлы.
В качестве альтернативы вы можете использовать пул потоков CLR для этого, что-то вроде
while (rdr.Read())
{
string line = rdr.Getring(0);
ThreadPool.QueueUserWorkItem (new WaitCallback(writeData), line);
}
и writeData будет выглядеть как
static void writeData(Object line)
{
string filename = String.Format("file{0}.txt", ++i);
File.WriteAllText(filename, line);
}
Недостаток использования ThreadPool заключается в том, что вы можете в итоге увеличить количество потоков, чем хотите, поскольку ваши потоки будут блокироваться в IO большую часть времени, пул потоков создаст новые потоки для обслуживания ваших запросов.
Сначала вы можете попробовать пул потоков и измерить производительность, если вы не удовлетворены, вы можете попробовать использовать 2 потока, 1 очередь; известный как проблема производителя/потребителя.
Вам будет полезно иметь больше потоков; лучший способ определить точное число - это эмпирически, но не ограничивайте себя одним ядром процессора так, как вы могли бы с задачами, связанными с CPU. Самый простой способ - использовать ThreadPool, но система массового обслуживания Producer/Consumer будет более гибкой и настраиваемой.
Почему бы не использовать пакет SSIS? Разве это не должно делать такие вещи?